typedef union
{
float
Elements[
6
];
struct
{
float
m11;
float
m12;
float
m21;
float
m22;
float
dx;
float
dy;
};
}MatrixElements,
*
PMatrixElements;
class
TransformMatrix
{
private
:
MatrixElements elements;
VOID ElementsInit(MatrixElements
&
e)
{
e.m11
=
e.m22
=
1.0f
;
e.m12
=
e.m21
=
e.dx
=
e.dy
=
0.0f
;
}
VOID ElementsMultiply(MatrixElements
&
e)
{
float
m11
=
elements.m11;
float
m12
=
elements.m12;
elements.m11
=
e.m11
*
m11
+
e.m12
*
elements.m21;
elements.m12
=
e.m11
*
m12
+
e.m12
*
elements.m22;
elements.m21
=
e.m21
*
m11
+
e.m22
*
elements.m21;
elements.m22
=
e.m21
*
m12
+
e.m22
*
elements.m22;
}
public
:
//
建立一个新实例,并初始化为单位矩阵 Elements = 1,0,0,1,0,0
TransformMatrix(VOID)
{
Reset();
}
//
建立一个新实例,并复制matrix的元素
TransformMatrix(TransformMatrix
*
matrix)
{
SetElements(matrix
->
elements);
}
TransformMatrix(TransformMatrix
&
matrix)
{
SetElements(matrix.elements);
}
//
建立一个按指定的元素初始化的新实例
TransformMatrix(
float
m11,
float
m12,
float
m21,
float
m22,
float
dx,
float
dy)
{
SetElements(m11, m12, m21, m22, dx, dy);
}
//
重置对象为单位矩阵
VOID Reset(VOID)
{
ElementsInit(elements);
}
//
将对象与matrix相乘
VOID Multiply(TransformMatrix
*
matrix)
{
//
float dx = elements.dx;
elements.dx
+=
(matrix
->
elements.dx
*
elements.m11
+
matrix
->
elements.dy
*
elements.m21);
elements.dy
+=
(matrix
->
elements.dx
*
elements.m12
+
matrix
->
elements.dy
*
elements.m22);
ElementsMultiply(matrix
->
elements);
}
VOID Multiply(TransformMatrix
&
matrix)
{
Multiply(
&
matrix);
}
//
设置平移
VOID Translate(
float
offsetX,
float
offsetY)
{
elements.dx
+=
(offsetX
*
elements.m11
+
offsetY
*
elements.m21);
elements.dy
+=
(offsetX
*
elements.m12
+
offsetY
*
elements.m22);
}
//
设置缩放
VOID Scale(
float
scaleX,
float
scaleY)
{
MatrixElements e;
ElementsInit(e);
e.m11
=
scaleX;
e.m22
=
scaleY;
ElementsMultiply(e);
}
//
设置剪切,注意不要将shearX, shearY同时设置为1
VOID Shear(
float
shearX,
float
shearY)
{
MatrixElements e;
ElementsInit(e);
e.m21
=
shearX;
e.m12
=
shearY;
ElementsMultiply(e);
}
//
设置按角度angle沿原点旋转
VOID Rotate(
float
angle)
{
MatrixElements e;
angle
=
angle
*
M_PI
/
180.0f
;
e.m11
=
e.m22
=
cos(angle);
e.m12
=
sin(angle);
e.m21
=
-
e.m12;
e.dx
=
e.dy
=
0.0f
;
ElementsMultiply(e);
}
//
设置按角度angle沿中心点centerX, centerY旋转
VOID RotateAt(
float
angle,
float
centerX,
float
centerY)
{
Translate(centerX, centerY);
Rotate(angle);
Translate(
-
centerX,
-
centerY);
}
//
如果此对象是可逆转的,则逆转该对象,返回TRUE;否则返回FALSE
BOOL Invert(VOID)
{
double
tmp
=
elements.m11
*
elements.m22
-
elements.m12
*
elements.m21;
if
((INT)(tmp
*
1000.0f
)
==
0
)
return
FALSE;
tmp
=
1.0f
/
tmp;
float
m11
=
elements.m11;
float
dx
=
-
elements.dx;
elements.m11
=
tmp
*
elements.m22;
elements.m12
=
tmp
*
-
elements.m12;
elements.m21
=
tmp
*
-
elements.m21;
elements.m22
=
tmp
*
m11;
elements.dx
=
dx
*
elements.m11
-
elements.dy
*
elements.m21;
elements.dy
=
dx
*
elements.m12
-
elements.dy
*
elements.m22;
return
TRUE;
}
//
按给定的大小计算并返回实施变换后的尺寸
VOID GetTransformSize(INT width, INT height,
float
&
fx,
float
&
fy,
float
&
fwidth,
float
&
fheight)
{
float
fxs[
3
], fys[
3
], v;
fxs[
1
]
=
fys[
0
]
=
0.0f
;
fxs[
0
]
=
fxs[
2
]
=
width;
fys[
1
]
=
fys[
2
]
=
height;
fx
=
fy
=
fwidth
=
fheight
=
0.0f
;
for
(INT i
=
0
; i
<
3
; i
++
)
{
v
=
fxs[i]
*
elements.m11
+
fys[i]
*
elements.m21;
if
(v
<
fx) fx
=
v;
else
if
(v
>
fwidth) fwidth
=
v;
v
=
fxs[i]
*
elements.m12
+
fys[i]
*
elements.m22;
if
(v
<
fy) fy
=
v;
else
if
(v
>
fheight) fheight
=
v;
}
fwidth
-=
fx;
fheight
-=
fy;
fx
+=
elements.dx;
fy
+=
elements.dy;
}
//
按给定的大小计算并返回实施变换后整型数矩形
VOID GetTransformRect(
int
width,
int
height, RECT
&
r)
{
float
fx, fy, fwidth, fheight;
GetTransformSize(width, height, fx, fy, fwidth, fheight);
r.left
=
(INT)fx;
r.top
=
(INT)fy;
r.right
=
(INT)(fwidth
+
fx
+
0.999999f
);
r.bottom
=
(INT)(fheight
+
fy
+
0.999999f
);
}
//
判断此对象是否是单位矩阵
BOOL GetIdentity(VOID)
{
return
(elements.m11
==
1.0f
&&
elements.m22
==
1.0f
&&
elements.m12
==
0.0f
&&
elements.m21
==
0.0f
&&
elements.dx
==
0.0f
&&
elements.dy
==
0.0f
);
}
//
获取对象的x偏移量
float
GetOffsetX(VOID)
{
return
elements.dx;
}
//
获取对象的y偏移量
float
GetOffsetY(VOID)
{
return
elements.dy;
}
//
判断对象是否是可逆转的。
BOOL GetInvertible(VOID)
{
return
(INT)(
1000.0f
*
(elements.m11
*
elements.m22
-
elements.m12
*
elements.m21))
!=
0
;
}
//
获取对象元素
MatrixElements
&
GetElements(VOID)
{
return
elements;
}
//
设置对象元素。注:设置元素是覆盖形式的
VOID SetElements(CONST MatrixElements
&
value)
{
SetElements(value.m11, value.m12, value.m21, value.m22, value.dx, value.dy);
}
VOID SetElements(
float
m11,
float
m12,
float
m21,
float
m22,
float
dx,
float
dy)
{
elements.m11
=
m11;
elements.m12
=
m12;
elements.m21
=
m21;
elements.m22
=
m22;
elements.dx
=
dx;
elements.dy
=
dy;
}
};