version 2.8
gmisc_matrix2d.c
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.org/license.html
6  */
7 
8 #include "../../gfx.h"
9 
10 #if GFX_USE_GMISC
11 
12 #if GMISC_NEED_MATRIXFLOAT2D
13 
14 #if !GMISC_NEED_FASTTRIG
15  #include <math.h>
16 #endif
17 
19  m->a00 = m->a11 = m->a22 = 1.0;
20  m->a01 = m->a02 = m->a10 = m->a12 = m->a20 = m->a21 = 0.0;
21 }
22 
23 void gmiscMatrixFloat2DMultiply(MatrixFloat2D *dst, const MatrixFloat2D *src1, const MatrixFloat2D *src2) {
24  dst->a00 = src1->a00*src2->a00 + src1->a01*src2->a10 + src1->a02*src2->a20;
25  dst->a01 = src1->a00*src2->a01 + src1->a01*src2->a11 + src1->a02*src2->a21;
26  dst->a02 = src1->a00*src2->a02 + src1->a01*src2->a12 + src1->a02*src2->a22;
27  dst->a10 = src1->a10*src2->a00 + src1->a11*src2->a10 + src1->a12*src2->a20;
28  dst->a11 = src1->a10*src2->a01 + src1->a11*src2->a11 + src1->a12*src2->a21;
29  dst->a12 = src1->a10*src2->a02 + src1->a11*src2->a12 + src1->a12*src2->a22;
30  dst->a20 = src1->a20*src2->a00 + src1->a21*src2->a10 + src1->a22*src2->a20;
31  dst->a21 = src1->a20*src2->a01 + src1->a21*src2->a11 + src1->a22*src2->a21;
32  dst->a22 = src1->a20*src2->a02 + src1->a21*src2->a12 + src1->a22*src2->a22;
33 }
34 
35 void gmiscMatrixFloat2DApplyTranslation(MatrixFloat2D *dst, const MatrixFloat2D *src, float tx, float ty) {
36  if (src) {
37  dst->a00 = src->a00; dst->a01 = src->a01; dst->a02 = src->a02+tx;
38  dst->a10 = src->a10; dst->a11 = src->a11; dst->a12 = src->a12+ty;
39  dst->a20 = src->a20; dst->a21 = src->a21; dst->a22 = src->a22;
40  } else {
41  dst->a00 = 1.0; dst->a01 = 0.0; dst->a02 = tx;
42  dst->a10 = 0.0; dst->a11 = 1.0; dst->a12 = ty;
43  dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
44  }
45 }
46 
47 void gmiscMatrixFloat2DApplyScale(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy) {
48  if (src) {
49  dst->a00 = src->a00*sx; dst->a01 = src->a01*sy; dst->a02 = src->a02;
50  dst->a10 = src->a10*sx; dst->a11 = src->a11*sy; dst->a12 = src->a12;
51  dst->a20 = src->a20*sx; dst->a21 = src->a21*sy; dst->a22 = src->a22;
52  } else {
53  dst->a00 = sx; dst->a01 = 0.0; dst->a02 = 0.0;
54  dst->a10 = 0.0; dst->a11 = sy; dst->a12 = 0.0;
55  dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
56  }
57 }
58 
59 void gmiscMatrixFloat2DApplyShear(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy) {
60  if (src) {
61  dst->a00 = src->a00 + src->a01*sy; dst->a01 = src->a00*sx + src->a01; dst->a02 = src->a02;
62  dst->a10 = src->a10 + src->a11*sy; dst->a11 = src->a10*sx + src->a11; dst->a12 = src->a12;
63  dst->a20 = src->a20 + src->a21*sy; dst->a21 = src->a20*sx + src->a21; dst->a22 = src->a22;
64  } else {
65  dst->a00 = 1.0; dst->a01 = sx; dst->a02 = 0.0;
66  dst->a10 = sy; dst->a11 = 1.0; dst->a12 = 0.0;
67  dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
68  }
69 }
70 
71 void gmiscMatrixFloat2DApplyRotation(MatrixFloat2D *dst, const MatrixFloat2D *src, int angle) {
72  float s, c;
73 
74  #if GMISC_NEED_FASTTRIG
75  s = fsin(angle);
76  c = fcos(angle);
77  #else
78  c = angle*GFX_PI/180;
79  s = sin(c);
80  c = cos(c);
81  #endif
82 
83  if (src) {
84  dst->a00 = src->a00*c - src->a01*s; dst->a01 = src->a00*s + src->a01*c; dst->a02 = src->a02;
85  dst->a10 = src->a10*c - src->a11*s; dst->a11 = src->a10*s + src->a11*c; dst->a12 = src->a12;
86  dst->a20 = src->a20*c - src->a21*s; dst->a21 = src->a20*s + src->a21*c; dst->a22 = src->a22;
87  } else {
88  dst->a00 = c; dst->a01 = s; dst->a02 = 0.0;
89  dst->a10 = -s; dst->a11 = c; dst->a12 = 0.0;
90  dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
91  }
92 }
93 
94 void gmiscMatrixFloat2DApplyToPoints(point *dst, const point *src, const MatrixFloat2D *m, int cnt) {
95  float x;
96 
97  for( ;cnt--; dst++, src++) {
98  x = src->x; // This allows in-place operation
99  dst->x = round(x*m->a00+src->y*m->a01+m->a02);
100  dst->y = round(x*m->a10+src->y*m->a11+m->a12);
101  }
102 }
103 
104 #endif // GMISC_NEED_MATRIXFLOAT2D
105 
106 #if GMISC_NEED_MATRIXFIXED2D
107 
109  m->a00 = m->a11 = m->a22 = FIXED(1);
110  m->a01 = m->a02 = m->a10 = m->a12 = m->a20 = m->a21 = 0;
111 }
112 
113 void gmiscMatrixFixed2DMultiply(MatrixFixed2D *dst, const MatrixFixed2D *src1, const MatrixFixed2D *src2) {
114  dst->a00 = FIXEDMUL(src1->a00,src2->a00) + FIXEDMUL(src1->a01,src2->a10) + FIXEDMUL(src1->a02,src2->a20);
115  dst->a01 = FIXEDMUL(src1->a00,src2->a01) + FIXEDMUL(src1->a01,src2->a11) + FIXEDMUL(src1->a02,src2->a21);
116  dst->a02 = FIXEDMUL(src1->a00,src2->a02) + FIXEDMUL(src1->a01,src2->a12) + FIXEDMUL(src1->a02,src2->a22);
117  dst->a10 = FIXEDMUL(src1->a10,src2->a00) + FIXEDMUL(src1->a11,src2->a10) + FIXEDMUL(src1->a12,src2->a20);
118  dst->a11 = FIXEDMUL(src1->a10,src2->a01) + FIXEDMUL(src1->a11,src2->a11) + FIXEDMUL(src1->a12,src2->a21);
119  dst->a12 = FIXEDMUL(src1->a10,src2->a02) + FIXEDMUL(src1->a11,src2->a12) + FIXEDMUL(src1->a12,src2->a22);
120  dst->a20 = FIXEDMUL(src1->a20,src2->a00) + FIXEDMUL(src1->a21,src2->a10) + FIXEDMUL(src1->a22,src2->a20);
121  dst->a21 = FIXEDMUL(src1->a20,src2->a01) + FIXEDMUL(src1->a21,src2->a11) + FIXEDMUL(src1->a22,src2->a21);
122  dst->a22 = FIXEDMUL(src1->a20,src2->a02) + FIXEDMUL(src1->a21,src2->a12) + FIXEDMUL(src1->a22,src2->a22);
123 }
124 
126  if (src) {
127  dst->a00 = src->a00; dst->a01 = src->a01; dst->a02 = src->a02+tx;
128  dst->a10 = src->a10; dst->a11 = src->a11; dst->a12 = src->a12+ty;
129  dst->a20 = src->a20; dst->a21 = src->a21; dst->a22 = src->a22;
130  } else {
131  dst->a00 = FIXED(1); dst->a01 = 0; dst->a02 = tx;
132  dst->a10 = 0; dst->a11 = FIXED(1); dst->a12 = ty;
133  dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
134  }
135 }
136 
137 void gmiscMatrixFixed2DApplyScale(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy) {
138  if (src) {
139  dst->a00 = FIXEDMUL(sx,src->a00); dst->a01 = FIXEDMUL(sy,src->a01); dst->a02 = src->a02;
140  dst->a10 = FIXEDMUL(sx,src->a10); dst->a11 = FIXEDMUL(sy,src->a11); dst->a12 = src->a12;
141  dst->a20 = FIXEDMUL(sx,src->a20); dst->a21 = FIXEDMUL(sy,src->a21); dst->a22 = src->a22;
142  } else {
143  dst->a00 = sx; dst->a01 = 0; dst->a02 = 0;
144  dst->a10 = 0; dst->a11 = sy; dst->a12 = 0;
145  dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
146  }
147 }
148 
149 void gmiscMatrixFixed2DApplyShear(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy) {
150  if (src) {
151  dst->a00 = src->a00 + FIXEDMUL(sy,src->a01); dst->a01 = FIXEDMUL(sx,src->a00) + src->a01; dst->a02 = src->a02;
152  dst->a10 = src->a10 + FIXEDMUL(sy,src->a11); dst->a11 = FIXEDMUL(sx,src->a10) + src->a11; dst->a12 = src->a12;
153  dst->a20 = src->a20 + FIXEDMUL(sy,src->a21); dst->a21 = FIXEDMUL(sx,src->a20) + src->a21; dst->a22 = src->a22;
154  } else {
155  dst->a00 = FIXED(1); dst->a01 = sx; dst->a02 = 0;
156  dst->a10 = sy; dst->a11 = FIXED(1); dst->a12 = 0;
157  dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
158  }
159 }
160 
161 #if GMISC_NEED_FIXEDTRIG
162  void gmiscMatrixFixed2DApplyRotation(MatrixFixed2D *dst, const MatrixFixed2D *src, int angle) {
163  fixed s, c;
164 
165  s = ffsin(angle);
166  c = ffcos(angle);
167 
168  if (src) {
169  dst->a00 = FIXEDMUL(c,src->a00) - FIXEDMUL(s,src->a01); dst->a01 = FIXEDMUL(s,src->a00) + FIXEDMUL(c,src->a01); dst->a02 = src->a02;
170  dst->a10 = FIXEDMUL(c,src->a10) - FIXEDMUL(s,src->a11); dst->a11 = FIXEDMUL(s,src->a10) + FIXEDMUL(c,src->a11); dst->a12 = src->a12;
171  dst->a20 = FIXEDMUL(c,src->a20) - FIXEDMUL(s,src->a21); dst->a21 = FIXEDMUL(s,src->a20) + FIXEDMUL(c,src->a21); dst->a22 = src->a22;
172  } else {
173  dst->a00 = c; dst->a01 = s; dst->a02 = 0;
174  dst->a10 = -s; dst->a11 = c; dst->a12 = 0;
175  dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
176  }
177  }
178 #endif
179 
180 void gmiscMatrixFixed2DApplyToPoints(point *dst, const point *src, const MatrixFixed2D *m, int cnt) {
181  coord_t x;
182 
183  for( ;cnt--; dst++, src++) {
184  x = src->x; // This allows in-place operation
185  dst->x = NONFIXED(x*m->a00+src->y*m->a01+m->a02+FIXED0_5);
186  dst->y = NONFIXED(x*m->a10+src->y*m->a11+m->a12+FIXED0_5);
187  }
188 }
189 
190 #endif // GMISC_NEED_MATRIXFIXED2D
191 
192 #endif // GFX_USE_GMISC
void gmiscMatrixFloat2DMultiply(MatrixFloat2D *dst, const MatrixFloat2D *src1, const MatrixFloat2D *src2)
Multiple two 2D matrixes together.
int16_t coord_t
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
void gmiscMatrixFixed2DApplyTranslation(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed tx, fixed ty)
Add an x,y translation to a matrix.
void gmiscMatrixFixed2DApplyRotation(MatrixFixed2D *dst, const MatrixFixed2D *src, int angle)
Add rotation to a matrix.
int32_t fixed
The type for a fixed point type.
Definition: gmisc.h:60
coord_t y
Definition: gdisp.h:53
void gmiscMatrixFixed2DMultiply(MatrixFixed2D *dst, const MatrixFixed2D *src1, const MatrixFixed2D *src2)
Multiple two 2D matrixes together.
void gmiscMatrixFloat2DApplyRotation(MatrixFloat2D *dst, const MatrixFloat2D *src, int angle)
Add rotation to a matrix.
void gmiscMatrixFixed2DApplyToPoints(point *dst, const point *src, const MatrixFixed2D *m, int cnt)
Apply the matrix to a set of points.
void gmiscMatrixFixed2DApplyShear(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy)
Add x,y shear to a matrix.
void gmiscMatrixFixed2DSetIdentity(MatrixFixed2D *m)
Set the 2D matrix to the identity matrix.
#define FIXED(x)
Macros to convert to and from a fixed point.
Definition: gmisc.h:66
Type for a 2D point on the screen.
Definition: gdisp.h:51
void gmiscMatrixFloat2DSetIdentity(MatrixFloat2D *m)
Set the 2D matrix to the identity matrix.
void gmiscMatrixFixed2DApplyScale(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy)
Add x,y scaling to a matrix.
void gmiscMatrixFloat2DApplyShear(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy)
Add x,y shear to a matrix.
fixed ffsin(int degrees)
Fast Table Based Trig functions.
void gmiscMatrixFloat2DApplyScale(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy)
Add x,y scaling to a matrix.
A matrix for doing 2D graphics using floats.
Definition: gmisc.h:237
A matrix for doing 2D graphics using fixed point maths.
Definition: gmisc.h:355
void gmiscMatrixFloat2DApplyToPoints(point *dst, const point *src, const MatrixFloat2D *m, int cnt)
Apply the matrix to a set of points.
coord_t x
Definition: gdisp.h:52
void gmiscMatrixFloat2DApplyTranslation(MatrixFloat2D *dst, const MatrixFloat2D *src, float tx, float ty)
Add an x,y translation to a matrix.
double fsin(int degrees)
Fast Table Based Trig functions.