二维图形变换

原理:马华东老师的课件

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

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);

}

平移
这里写图片描述

缩放
这里写图片描述

错切
这里写图片描述

关于原点对称
这里写图片描述

旋转
这里写图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值