FastLED 3.9.15
Loading...
Searching...
No Matches
transform.cpp.hpp
Go to the documentation of this file.
1
2#include "fl/math/math.h"
3
4#include "fl/math/lut.h"
5#include "fl/math/math.h"
6#include "fl/math/transform.h"
7#include "fl/math/intmap.h"
8#include "fl/math/trig8.h"
10
13
14namespace fl {
15
17 if (is_identity()) {
18 return xy;
19 }
20 float x = xy.x;
21 float y = xy.y;
22 if (scale_x != 1.0f) {
23 x *= scale_x;
24 }
25 if (scale_y != 1.0f) {
26 y *= scale_y;
27 }
28 // Assume that adding floats is fast when offset_x == 0.0f
29 x += offset_x;
30 y += offset_y;
31
32 const bool has_rotation = (rotation != 0.0f);
33
34 if (has_rotation) {
35 float radians = rotation * 2 * FL_PI;
36 float cos_theta = cosf(radians);
37 float sin_theta = sinf(radians);
38 float x_rotated = x * cos_theta - y * sin_theta;
39 float y_rotated = x * sin_theta + y * cos_theta;
40 return vec2f(x_rotated, y_rotated);
41 }
42 return vec2f(x, y);
43}
44
45Transform16 Transform16::ToBounds(alpha16 max_value) {
46 Transform16 tx;
47 // Compute a Q16 “scale” so that:
48 // (alpha16 * scale) >> 16 == max_value when alpha16==0xFFFF
49 alpha16 scale16 = 0;
50 if (max_value) {
51 // numerator = max_value * 2^16
52 u32 numer = static_cast<u32>(max_value) << 16;
53 // denom = 0xFFFF; use ceil so 0xFFFF→max_value exactly:
54 u32 scale32 = numer / 0xFFFF;
55 scale16 = static_cast<alpha16>(scale32);
56 }
57 tx.scale_x = scale16;
58 tx.scale_y = scale16;
59 tx.offset_x = 0;
60 tx.offset_y = 0;
61 tx.rotation = 0;
62 return tx;
63}
64
65Transform16 Transform16::ToBounds(const vec2<alpha16> &min,
66 const vec2<alpha16> &max, alpha16 rotation) {
67 Transform16 tx;
68 // Compute a Q16 “scale” so that:
69 // (alpha16 * scale) >> 16 == max_value when alpha16==0xFFFF
70 alpha16 scale16 = 0;
71 if (max.x > min.x) {
72 // numerator = max_value * 2^16
73 u32 numer = static_cast<u32>(max.x - min.x) << 16;
74 // denom = 0xFFFF; use ceil so 0xFFFF→max_value exactly:
75 u32 scale32 = numer / 0xFFFF;
76 scale16 = static_cast<alpha16>(scale32);
77 }
78 tx.scale_x = scale16;
79 if (max.y > min.y) {
80 // numerator = max_value * 2^16
81 u32 numer = static_cast<u32>(max.y - min.y) << 16;
82 // denom = 0xFFFF; use ceil so 0xFFFF→max_value exactly:
83 u32 scale32 = numer / 0xFFFF;
84 scale16 = static_cast<alpha16>(scale32);
85 }
86 tx.scale_y = scale16;
87 tx.offset_x = min.x;
88 tx.offset_y = min.y;
89 tx.rotation = rotation;
90 return tx;
91}
92
93vec2<alpha16> Transform16::transform(const vec2<alpha16> &xy) const {
94 vec2<alpha16> out = xy;
95
96 // 1) Rotate around the 16‑bit center first
97 if (rotation != 0) {
98 constexpr i32 MID = 0x7FFF; // center of 0…0xFFFF interval
99
100 // bring into signed centered coords
101 i32 x = i32(out.x) - MID;
102 i32 y = i32(out.y) - MID;
103
104 // Q15 cosine & sine
105 i32 c = cos16(rotation); // [-32768..+32767]
106 i32 s = sin16(rotation);
107
108 // rotate & truncate
109 i32 xr = (x * c - y * s) >> 15;
110 i32 yr = (x * s + y * c) >> 15;
111
112 // shift back into [0…0xFFFF]
113 out.x = alpha16(xr + MID);
114 out.y = alpha16(yr + MID);
115 }
116
117 // 2) Then scale in X/Y (Q16 → map32_to_16)
118 if (scale_x != 0xFFFF) {
119 u32 tx = u32(out.x) * scale_x;
120 out.x = map32_to_16(tx);
121 }
122 if (scale_y != 0xFFFF) {
123 u32 ty = u32(out.y) * scale_y;
124 out.y = map32_to_16(ty);
125 }
126
127 // 3) Finally translate
128 if (offset_x)
129 out.x = alpha16(out.x + offset_x);
130 if (offset_y)
131 out.y = alpha16(out.y + offset_y);
132
133 return out;
134}
135
136float TransformFloatImpl::scale() const { return fl::min(scale_x, scale_y); }
137
139 scale_x = scale;
140 scale_y = scale;
141}
142
144 return (scale_x == 1.0f && scale_y == 1.0f && offset_x == 0.0f &&
145 offset_y == 0.0f && rotation == 0.0f);
146}
147
148Matrix3x3f TransformFloat::compile() const {
149 Matrix3x3f out;
150 out.m[0][0] = scale_x() * cosf(rotation() * 2.0f * FL_PI);
151 out.m[0][1] = -scale_y() * sinf(rotation() * 2.0f * FL_PI);
152 out.m[0][2] = offset_x();
153 out.m[1][0] = scale_x() * sinf(rotation() * 2.0f * FL_PI);
154 out.m[1][1] = scale_y() * cosf(rotation() * 2.0f * FL_PI);
155 out.m[1][2] = offset_y();
156 out.m[2][2] = 1.0f;
157 return out;
158}
159
160} // namespace fl
161
int y
Definition simple.h:93
int x
Definition simple.h:92
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
Memory functions are available in fl:: namespace via fl/stl/cstring.h Using declarations cannot work ...
Definition math.h:71
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
Definition math.h:75
constexpr T radians(T deg) FL_NOEXCEPT
Definition math.h:522
uint32_t scale_y[NUM_LAYERS]
Definition Fire2023.h:95
uint32_t scale_x[NUM_LAYERS]
Definition Fire2023.h:94
fl::UISlider scale("Scale", 4,.1, 4,.1)
unsigned int xy(unsigned int x, unsigned int y)
bool is_identity() const
void set_scale(float scale)
vec2f transform(const vec2f &xy) const
Integer mapping functions between different integer sizes.
Legacy compatibility header for trigonometry functions.
u16 map32_to_16(u32 x) FL_NOEXCEPT
Definition intmap.h:72
#define FL_PI
Definition math.h:26
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
Definition math.h:71
vec2< float > vec2f
Definition geometry.h:333
float sinf(float value) FL_NOEXCEPT
Definition math.h:352
float cosf(float value) FL_NOEXCEPT
Definition math.h:358
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_DISABLE_WARNING(warning)
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
float m[3][3]
Definition transform.h:95
Transform16()=default
vec2< alpha16 > transform(const vec2< alpha16 > &xy) const
static Transform16 ToBounds(alpha16 max_value)
alpha16 scale_x
Definition transform.h:47
alpha16 rotation
Definition transform.h:51
alpha16 offset_x
Definition transform.h:49
alpha16 offset_y
Definition transform.h:50
float offset_x() const
Definition transform.h:108
float scale_x() const
Definition transform.h:106
float offset_y() const
Definition transform.h:109
float rotation() const
Definition transform.h:111
float scale_y() const
Definition transform.h:107
Matrix3x3f compile() const