xref: /haiku/src/tests/kits/interface/picture/Matrix.h (revision c237c4ce593ee823d9867fd997e51e4c447f5623)
1 #ifndef _MATRIX_H
2 #define _MATRIX_H
3 
4 // Standard Includes -----------------------------------------------------------
5 
6 // System Includes -------------------------------------------------------------
7 #include <Point.h>
8 
9 // Project Includes ------------------------------------------------------------
10 
11 // Local Includes --------------------------------------------------------------
12 
13 // Local Defines ---------------------------------------------------------------
14 
15 // Globals ---------------------------------------------------------------------
16 
17 // BMatrix class ---------------------------------------------------------------
18 class BMatrix {
19 
20 public:
21 				BMatrix();
22 
23 		void	Translate(float tx, float ty);
24 		void	Rotate(float angle);
25 		void	Scale(float scaleFactorX, float scaleFactorY);
26 		void	SkewX(float angle);
27 		void	SkewY(float angle);
28 
29 		void	Transform(BPoint *point);
30 		BPoint	Transform(BPoint point);
31 		void	Transform(BShape &shape);
32 
33 		BMatrix &operator*=(const BMatrix &matrix);
34 
35 		float a, b, c, d, e, f;
36 };
37 // BTransformIterator class ----------------------------------------------------
38 class BTransformIterator : public BShapeIterator {
39 
40 public:
41 						BTransformIterator(BMatrix *matrix);
42 
43 virtual	status_t		IterateMoveTo(BPoint *point);
44 virtual	status_t		IterateLineTo(int32 lineCount, BPoint *linePts);
45 virtual	status_t		IterateBezierTo(int32 bezierCount, BPoint *bezierPts);
46 virtual	status_t		IterateClose();
47 
48 private:
49 
50 		BMatrix			*fMatrix;
51 };
52 //------------------------------------------------------------------------------
53 inline BMatrix::BMatrix()
54 {
55 	a = d = 1.0f;
56 	b = c = e = f = 0.0f;
57 }
58 //------------------------------------------------------------------------------
59 inline void BMatrix::Translate(float tx, float ty)
60 {
61 	e += a * tx + c * ty;
62 	f += b * tx + d * ty;
63 }
64 //------------------------------------------------------------------------------
65 inline void BMatrix::Rotate(float angle)
66 {
67 	BMatrix m;
68 	angle = (float)(angle * 3.1415926535897932384626433832795 / 180.0);
69 	float ca = (float)cos(angle), sa = (float)sin(angle);
70 
71 	m.a = a * ca + c * sa;
72 	m.b = b * ca + d * sa;
73 	m.c = - a * sa + c * ca;
74 	m.d = - b * sa + d * ca;
75 	m.e = e;
76 	m.f = f;
77 
78 	*this = m;
79 }
80 //------------------------------------------------------------------------------
81 inline void BMatrix::Scale(float scaleFactorX, float scaleFactorY)
82 {
83 	BMatrix m;
84 
85 	m.a = a * scaleFactorX;
86 	m.b = b * scaleFactorX;
87 	m.c = c * scaleFactorY;
88 	m.d = d * scaleFactorY;
89 	m.e = e;
90 	m.f = f;
91 
92 	*this = m;
93 }
94 //------------------------------------------------------------------------------
95 inline void BMatrix::SkewX(float angle)
96 {
97 	BMatrix m;
98 	angle = (float)(angle * 3.1415926535897932384626433832795 / 180.0);
99 	float x = (float)tan(angle);
100 
101 	m.a = a;
102 	m.b = b;
103 	m.c = a * x + c;
104 	m.d = b * x + d;
105 	m.e = e;
106 	m.f = f;
107 
108 	*this = m;
109 }
110 //------------------------------------------------------------------------------
111 inline void BMatrix::SkewY(float angle)
112 {
113 	BMatrix m;
114 	angle = (float)(angle * 3.1415926535897932384626433832795 / 180.0);
115 	float y = (float)tan(angle);
116 
117 	m.a = a + c * y;
118 	m.b = b + d * y;
119 	m.c = c;
120 	m.d = d;
121 	m.e = e;
122 	m.f = f;
123 
124 	*this = m;
125 }
126 //------------------------------------------------------------------------------
127 inline void BMatrix::Transform(BPoint *point)
128 {
129 	float x = point->x;
130 	float y = point->y;
131 
132 	point->x = x * a + y * c + e;
133 	point->y = x * b + y * d + f;
134 }
135 //------------------------------------------------------------------------------
136 inline BPoint BMatrix::Transform(BPoint point)
137 {
138 	Transform(&point);
139 	return point;
140 }
141 //------------------------------------------------------------------------------
142 inline void BMatrix::Transform(BShape &shape)
143 {
144 	BTransformIterator transform(this);
145 	transform.Iterate(&shape);
146 }
147 //------------------------------------------------------------------------------
148 inline BMatrix &BMatrix::operator*=(const BMatrix &matrix)
149 {
150 	BMatrix m;
151 
152 	m.a = a * matrix.a + c * matrix.b;
153 	m.b = b * matrix.a + d * matrix.b;
154 	m.c = a * matrix.c + c * matrix.d;
155 	m.d = b * matrix.c + d * matrix.d;
156 	m.e = a * matrix.e + c * matrix.f + e;
157 	m.f = b * matrix.e + d * matrix.f + f;
158 
159 	*this = m;
160 
161 	return *this;
162 }
163 //------------------------------------------------------------------------------
164 inline BTransformIterator::BTransformIterator(BMatrix *matrix)
165 {
166 	fMatrix = matrix;
167 }
168 //------------------------------------------------------------------------------
169 inline status_t BTransformIterator::IterateMoveTo(BPoint *point)
170 {
171 	fMatrix->Transform(point);
172 	return B_OK;
173 }
174 //------------------------------------------------------------------------------
175 inline status_t BTransformIterator::IterateLineTo(int32 lineCount, BPoint *linePts)
176 {
177 	for (int32 i = 0; i < lineCount; i++)
178 		fMatrix->Transform(linePts++);
179 	return B_OK;
180 }
181 //------------------------------------------------------------------------------
182 inline status_t BTransformIterator::IterateBezierTo(int32 bezierCount,
183 											 BPoint *bezierPts)
184 {
185 	for (int32 i = 0; i < bezierCount * 3; i++)
186 		fMatrix->Transform(bezierPts++);
187 	return B_OK;
188 }
189 //------------------------------------------------------------------------------
190 inline status_t BTransformIterator::IterateClose()
191 {
192 	return B_OK;
193 }
194 //------------------------------------------------------------------------------
195 
196 #endif // _MATRIX_H
197