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