]> git.sesse.net Git - nageru/blob - flow2rgb.h
Write a .flo file for easier evaluation.
[nageru] / flow2rgb.h
1 #ifndef _FLOW2RGB_H
2 #define _FLOW2RGB_H 1
3
4 #include <math.h>
5 #include <stdint.h>
6
7 #include <algorithm>
8
9 // du and dv are in pixels.
10 inline void flow2rgb(float du, float dv, uint8_t *rr, uint8_t *gg, uint8_t *bb)
11 {
12         float angle = atan2(dv, du);
13         float magnitude = std::min(hypot(du, dv) / 20.0, 1.0);
14         
15         // HSV to RGB (from Wikipedia). Saturation is 1.
16         float c = magnitude;
17         float h = (angle + M_PI) * 6.0 / (2.0 * M_PI);
18         float X = c * (1.0 - fabs(fmod(h, 2.0) - 1.0));
19         float r = 0.0f, g = 0.0f, b = 0.0f;
20         if (h < 1.0f) {
21                 r = c; g = X;
22         } else if (h < 2.0f) {
23                 r = X; g = c;
24         } else if (h < 3.0f) {
25                 g = c; b = X;
26         } else if (h < 4.0f) {
27                 g = X; b = c;
28         } else if (h < 5.0f) {
29                 r = X; b = c;
30         } else if (h < 6.0f) {
31                 r = c; b = X;
32         } else {
33                 // h is NaN, so black is fine.
34         }
35         float m = magnitude - c;
36         r += m; g += m; b += m;
37         r = std::max(std::min(r, 1.0f), 0.0f);
38         g = std::max(std::min(g, 1.0f), 0.0f);
39         b = std::max(std::min(b, 1.0f), 0.0f);
40         *rr = lrintf(r * 255.0f);
41         *gg = lrintf(g * 255.0f);
42         *bb = lrintf(b * 255.0f);
43 }
44
45 #endif  // !defined(_FLOW2RGB_H)