原理:马华东老师的课件
class Matrix2D
{
public:
float m[3][3]; //上面2*2部分包含线性变换,最后一行为平移变换
CPoint cal(CPoint &p); //计算变换后的坐标
void translation(float dx, float dy); //平移
void scaling(float sx, float sy); //缩放
void shear(float sx, float sy); //错切
void mirror(int axis); //对称
void rotation(float theta); //绕原点逆时针旋转theta角度
};
//计算变换后的坐标
CPoint Matrix2D::cal(CPoint &p)
{
CPoint q;
q.x = p.x * m[0][0] + p.y * m[1][0] + m[2][0];
q.y = p.x * m[0][1] + p.y * m[1][1] + m[2][1];
return q;
}
//平移
void Matrix2D::translation(float dx, float dy)
{
m[0][0] = 1; m[0][1] = 0; m[0][2] = 0;
m[1][0] = 0; m[1][1] = 1; m[1][2] = 0;
m[2][0] = dx; m[2][1] = dy; m[2][2] = 1;
}
//缩放
void Matrix2D::scaling(float sx, float sy)
{
m[0][0] = sx; m[0][1] = 0; m[0][2] = 0;
m[1][0] = 0; m[1][1] = sy; m[1][2] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1;
}
//错切
//x' = x + by
//y' = y + dx
void Matrix2D::shear(float b, float d)
{
m[0][0] = 1; m[0][1] = d; m[0][2] = 0;
m[1][0] = b; m[1][1] = 1; m[1][2] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1;
}
//对称
void Matrix2D::mirror(int axis)
{
float a, b, d, e;
if(axis == 0) //关于x轴对称
{
a = 1;
e = -1;
b = d = 0;
}
else if(axis == 1) //关于y轴对称
{
a = -1;
e = 1;
b = d = 0;
}
else if(axis == 2) //关于原点对称
{
a = -1;
e = -1;
b = d = 0;
}
else if(axis == 3) //关于y=x对称
{
a = 0;
e = 0;
b = d = 1;
}
else if(axis == 4) //关于y=-x对称
{
a = 0;
e = 0;
b = d = -1;
}
m[0][0] = a; m[0][1] = d; m[0][2] = 0;
m[1][0] = b; m[1][1] = e; m[1][2] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1;
}
//绕原点逆时针旋转theta角度,如果theta<0,顺时针旋转
void Matrix2D::rotation(float theta)
{
m[0][0] = cos(theta); m[0][1] = sin(theta); m[0][2] = 0;
m[1][0] = -sin(theta); m[1][1] = cos(theta); m[1][2] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1;
}
//画矩形
void draw(CPoint *points, CDC *pDC)
{
//设置绘图对象
CPen newpen(PS_SOLID, 1, RGB(255, 0, 0)), *oldpen;
oldpen = pDC->SelectObject(&newpen);
pDC->MoveTo(points[0].x, points[0].y);
pDC->LineTo(points[1].x, points[1].y);
pDC->MoveTo(points[1].x, points[1].y);
pDC->LineTo(points[2].x, points[2].y);
pDC->MoveTo(points[2].x, points[2].y);
pDC->LineTo(points[3].x, points[3].y);
pDC->MoveTo(points[3].x, points[3].y);
pDC->LineTo(points[0].x, points[0].y);
pDC->SelectObject(oldpen);
}
void CMy2DchangeView::OnDraw(CDC* pDC)
{
CMy2DchangeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int x[4] = {100, 200, 200, 100};
int y[4] = {100, 100, 200, 200};
CPoint p[4];
for(int i=0; i<4; i++)
{
p[i].x = x[i];
p[i].y = y[i];
}
//draw(p, pDC);
Matrix2D m;
/*
平移测试
m.translation(50, 50);
*/
/*
缩放测试
m.scaling(1.5, 1);
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
m.translation(100, 0);
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
*/
/*错切测试
m.shear(1.5, 1);
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
m.translation(-30, -100);
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
*/
/*
对称测试
int x1[4] = {-10, -110, -110, -10};
int y1[4] = {-10, -10, -110, -110};
for(i=0; i<4; i++)
{
p[i].x = x1[i];
p[i].y = y1[i];
}
m.translation(250, 250); //将原图形经平移后再显示
CPoint p1[4];
for(i=0; i<4; i++)
p1[i] = m.cal(p[i]);
draw(p1, pDC);
pDC->MoveTo(250, 250); //画出坐标轴
pDC->LineTo(500, 250);
pDC->MoveTo(250, 250);
pDC->LineTo(0, 250);
pDC->MoveTo(250, 250);
pDC->LineTo(250, 250);
pDC->MoveTo(250, 500);
pDC->LineTo(250, 0);
m.mirror(2);
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
m.translation(250, 250); //将对称变换后的图形经平移后再显示
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
draw(p, pDC);
*/
//旋转测试
m.rotation(60*3.14/180);
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
m.translation(400, -50); //将旋转变换后的图形经平移后再显示
for(i=0; i<4; i++)
p[i] = m.cal(p[i]);
draw(p, pDC);
}
平移
缩放
错切
关于原点对称
旋转