35 float vx,
float vy)
noexcept {
36 constexpr float rad2ang = 360.0f / (2.0f *
static_cast<float>(M_PI));
37 float angle = 180.0f + std::atan2(vy, vx) * rad2ang;
39 angle = 360.0f + angle;
41 angle = std::fmod(angle, 360.0f);
43 const float norm = std::sqrt(vx * vx + vy * vy);
44 constexpr float shift = 0.999f;
45 const float a = 1.0f / std::log(0.1f + shift);
46 const float intensity = std::clamp(a * std::log(norm + shift), 0.0f, 1.0f);
48 const float h_60 = angle * (1.0f / 60.0f);
49 const float saturation = 1.0f;
51 const float c = value * saturation;
52 const float x = c * (1.0f - std::abs(std::fmod(h_60, 2.0f) - 1.0f));
53 const float m = value - c;
58 switch (
static_cast<unsigned int>(h_60)) {
97 static_cast<uint8_t
>((b + m) * 255.0f),
98 static_cast<uint8_t
>((g + m) * 255.0f),
99 static_cast<uint8_t
>((r + m) * 255.0f),
100 static_cast<uint8_t
>(0),
107 uint32_t height, uint32_t width,
const float *data) {
108 const size_t pixel_count =
static_cast<size_t>(height) *
static_cast<size_t>(width);
109 std::vector<uint8_t> out;
110 out.resize(pixel_count * 4u);
111 for (
size_t i = 0; i < pixel_count; ++i) {
112 const float vx = data[i * 2u];
113 const float vy = data[i * 2u + 1u];
115 out[i * 4u + 0u] = bgra[0];
116 out[i * 4u + 1u] = bgra[1];
117 out[i * 4u + 2u] = bgra[2];
118 out[i * 4u + 3u] = bgra[3];