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 ---------------------------------------------------------------
18class BMatrix {
19
20public:
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 ----------------------------------------------------
38class BTransformIterator : public BShapeIterator {
39
40public:
41						BTransformIterator(BMatrix *matrix);
42
43virtual	status_t		IterateMoveTo(BPoint *point);
44virtual	status_t		IterateLineTo(int32 lineCount, BPoint *linePts);
45virtual	status_t		IterateBezierTo(int32 bezierCount, BPoint *bezierPts);
46virtual	status_t		IterateClose();
47
48private:
49
50		BMatrix			*fMatrix;
51};
52//------------------------------------------------------------------------------
53inline BMatrix::BMatrix()
54{
55	a = d = 1.0f;
56	b = c = e = f = 0.0f;
57}
58//------------------------------------------------------------------------------
59inline void BMatrix::Translate(float tx, float ty)
60{
61	e += a * tx + c * ty;
62	f += b * tx + d * ty;
63}
64//------------------------------------------------------------------------------
65inline 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//------------------------------------------------------------------------------
81inline 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//------------------------------------------------------------------------------
95inline 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//------------------------------------------------------------------------------
111inline 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//------------------------------------------------------------------------------
127inline 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//------------------------------------------------------------------------------
136inline BPoint BMatrix::Transform(BPoint point)
137{
138	Transform(&point);
139	return point;
140}
141//------------------------------------------------------------------------------
142inline void BMatrix::Transform(BShape &shape)
143{
144	BTransformIterator transform(this);
145	transform.Iterate(&shape);
146}
147//------------------------------------------------------------------------------
148inline 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//------------------------------------------------------------------------------
164inline BTransformIterator::BTransformIterator(BMatrix *matrix)
165{
166	fMatrix = matrix;
167}
168//------------------------------------------------------------------------------
169inline status_t BTransformIterator::IterateMoveTo(BPoint *point)
170{
171	fMatrix->Transform(point);
172	return B_OK;
173}
174//------------------------------------------------------------------------------
175inline 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//------------------------------------------------------------------------------
182inline 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//------------------------------------------------------------------------------
190inline status_t BTransformIterator::IterateClose()
191{
192	return B_OK;
193}
194//------------------------------------------------------------------------------
195
196#endif // _MATRIX_H
197