二维点类
class CPoint2
{
public:CPoint2();CPoint2(double x, double y);~CPoint2();friend CPoint2 operator +(const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator -(const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator *(const CPoint2& p0, double t);friend CPoint2 operator *(double t, const CPoint2& p0);friend CPoint2 operator /(const CPoint2& p0, double t);friend CPoint2 operator +=(const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator -=(const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator *=(const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator /=(const CPoint2& p0, const CPoint2& p1);
public:double m_x, m_y, m_w;
};
CPoint2::CPoint2()
{m_x = 0;m_y = 0;m_w = 1;
}CPoint2::CPoint2(double x, double y)
{m_x = x;m_y = y;m_w = 1;
}CPoint2::~CPoint2()
{
}CPoint2 operator+(const CPoint2& p0, const CPoint2& p1)
{CPoint2 res;res.m_x = p0.m_x + p1.m_x;res.m_y = p0.m_y + p1.m_y;return res;
}CPoint2 operator-(const CPoint2& p0, const CPoint2& p1)
{CPoint2 res;res.m_x = p0.m_x - p1.m_x;res.m_y = p0.m_y - p0.m_y;return res;
}CPoint2 operator*(const CPoint2& p0, double t)
{CPoint2 res;res.m_x = p0.m_x * t;res.m_y = p0.m_y + t;return res;
}CPoint2 operator*(double t, const CPoint2& p0)
{CPoint2 res;res.m_x = p0.m_x * t;res.m_y = p0.m_y * t;return res;
}CPoint2 operator/(const CPoint2& p0, double t)
{if (fabs(t) < 1e-4)t = 1.0;CPoint2 res;res.m_x = p0.m_x / t;res.m_y = p0.m_y / t;return res;
}CPoint2 operator+=(CPoint2& p0, CPoint2& p1)
{p0.m_x += p1.m_x;p0.m_y += p1.m_y;return p0;
}CPoint2 operator-=(CPoint2& p0,CPoint2& p1)
{p0.m_x -= p1.m_x;p0.m_y -= p1.m_y;return p0;
}CPoint2 operator*=(CPoint2& p0, CPoint2& p1)
{p0.m_x *= p1.m_x;p0.m_y *= p1.m_y;return p0;
}CPoint2 operator/=(CPoint2& p0,CPoint2& p1)
{if (fabs(p1.m_x) < 1e-4||fabs(p1.m_y)<1e-4)p1.m_x = 1.0,p1.m_y=1.0;p0.m_x /= p1.m_x;p0.m_y /= p1.m_y;return p0;
}
二维变换类
class CTransform2
{
public:CTransform2();~CTransform2();void SetMatrix(CPoint2* p, int pNum);//设置矩阵void IdentityMatrix();//单位矩阵void Translate(double tx, double ty);void Translate(double tx, double ty, CPoint2 p);void Scale(double sx, double sy);void Scale(double sx, double sy, CPoint2 p);void Rotate(double beta);void Rotate(double beta, CPoint2 p);void SymmetryO();void SymmetryX();void SymmetryY();void Shear(double lambdax, double lambday);void Shear(double lambdax, double lambday,CPoint2 p);void MatrixMultiply();public:double m_matrix[3][3];CPoint2* m_p;int m_pNum;
};CTransform2::CTransform2()
{
}CTransform2::~CTransform2()
{
}void CTransform2::SetMatrix(CPoint2* p, int pNum)
{m_p = p;m_pNum = pNum;
}void CTransform2::IdentityMatrix()
{m_matrix[0][0] = 1.0; m_matrix[0][0] = 0.0; m_matrix[0][0] = 0.0;m_matrix[0][0] = 0.0; m_matrix[0][0] = 1.0; m_matrix[0][0] = 0.0;m_matrix[0][0] = 0.0; m_matrix[0][0] = 0.0; m_matrix[0][0] = 1.0;}void CTransform2::Translate(double tx, double ty)
{IdentityMatrix();m_matrix[0][2] = tx;m_matrix[1][2] = ty;MatrixMultiply();
}void CTransform2::Translate(double tx, double ty, CPoint2 p)
{
}void CTransform2::Scale(double sx, double sy)
{IdentityMatrix();m_matrix[0][0] = sx;m_matrix[1][1] = sy;MatrixMultiply();
}void CTransform2::Scale(double sx, double sy, CPoint2 p)
{IdentityMatrix();m_matrix[0][0] = sx;m_matrix[0][0] = p.m_x*(1-sx);m_matrix[1][1] = sy;m_matrix[1][2] = p.m_y*(1-sy);MatrixMultiply();
}void CTransform2::Rotate(double beta)
{IdentityMatrix();m_matrix[0][0] = cos(beta * PI / 180);m_matrix[0][1] = -sin(beta * PI / 180);m_matrix[1][0] = sin(beta * PI / 180);m_matrix[1][1] = cos(beta * PI / 180);MatrixMultiply();
}void CTransform2::Rotate(double beta, CPoint2 p)
{IdentityMatrix();m_matrix[0][0] = cos(beta * PI / 180);m_matrix[0][1] = -sin(beta * PI / 180);m_matrix[0][2] = p.m_x * (1 - cos(beta)) + p.m_y * sin(beta);m_matrix[1][0] = sin(beta * PI / 180);m_matrix[1][1] = cos(beta * PI / 180);m_matrix[1][2] = p.m_y * (1 - cos(beta)) + p.m_y * sin(beta);MatrixMultiply();
}void CTransform2::SymmetryO()
{IdentityMatrix();m_matrix[0][0] = -1;m_matrix[1][1] = -1;MatrixMultiply();
}void CTransform2::SymmetryX()
{IdentityMatrix();m_matrix[1][1] = -1;MatrixMultiply();
}void CTransform2::SymmetryY()
{IdentityMatrix();m_matrix[0][0] = -1;MatrixMultiply();
}void CTransform2::Shear(double lambdax, double lambday)
{IdentityMatrix();m_matrix[0][1] = lambdax;m_matrix[1][0] = lambday;MatrixMultiply();
}void CTransform2::Shear(double lambdax, double lambday, CPoint2 p)
{IdentityMatrix();m_matrix[0][1] = lambdax;m_matrix[0][2] = -p.m_x * lambdax;m_matrix[1][0] = lambday;m_matrix[1][2] = -p.m_y * lambday;MatrixMultiply();
}void CTransform2::MatrixMultiply()
{CPoint2 *pTemp = new CPoint2[m_pNum];for (int i = 0; i < m_pNum; i++) {pTemp[i]=m_p[i];}for (int i = 0; i < m_pNum; i++) {m_p[i].m_x = m_matrix[0][0] * pTemp[i].m_x+ m_matrix[0][1] * pTemp[i].m_y + m_matrix[0][2] * pTemp[i].m_w;m_p[i].m_y = m_matrix[1][0] * pTemp[i].m_x+ m_matrix[1][1] * pTemp[i].m_y + m_matrix[1][2] * pTemp[i].m_w;m_p[i].m_w = m_matrix[2][0] * pTemp[i].m_x+ m_matrix[2][1] * pTemp[i].m_y + m_matrix[2][2] * pTemp[i].m_w;}delete[] pTemp;
}
基本图元
class CBasic
{
public:CBasic();~CBasic();void Draw(CDC* pDC);
public:CPoint2 m_p[12];
};
CBasic::CBasic()
{m_p[0] = CPoint2(20, 20);m_p[1] = CPoint2(-20, 20);m_p[2] = CPoint2(-20, -20);m_p[3] = CPoint2(20, -20);m_p[4] = CPoint2(50, 50);m_p[5] = CPoint2(-50, 50);m_p[6] = CPoint2(-50, -50);m_p[7] = CPoint2(50, -50);m_p[8] = CPoint2((m_p[4].m_x + m_p[7].m_x) / 2 + 40, (m_p[4].m_y + m_p[7].m_y) / 2);m_p[9] = CPoint2((m_p[4].m_x + m_p[5].m_x) / 2, (m_p[4].m_y + m_p[5].m_y) / 2 + 40);m_p[10] = CPoint2((m_p[5].m_x + m_p[6].m_x) / 2 - 40, (m_p[5].m_y + m_p[6].m_y) / 2);m_p[11] = CPoint2((m_p[6].m_x + m_p[7].m_x) / 2, (m_p[6].m_y + m_p[7].m_y) / 2 - 40);
}
CBasic::~CBasic()
{
}void CBasic::Draw(CDC* pDC)
{CPen NewPen(PS_SOLID, 3, RGB(0, 0, 0));auto OldPen = pDC->SelectObject(&NewPen);pDC->MoveTo(m_p[0].m_x, m_p[0].m_y);pDC->LineTo(m_p[1].m_x, m_p[1].m_y);pDC->LineTo(m_p[2].m_x, m_p[2].m_y);NewPen.DeleteObject();NewPen.CreatePen(PS_SOLID, 3, RGB(255, 0, 0));OldPen = pDC->SelectObject(&NewPen);pDC->LineTo(m_p[3].m_x, m_p[3].m_y);pDC->LineTo(m_p[0].m_x, m_p[0].m_y);NewPen.DeleteObject();NewPen.CreatePen(PS_SOLID, 3, RGB(0,255, 0));OldPen = pDC->SelectObject(&NewPen);pDC->MoveTo(m_p[4].m_x, m_p[4].m_y);pDC->LineTo(m_p[5].m_x, m_p[5].m_y);pDC->LineTo(m_p[6].m_x, m_p[6].m_y);NewPen.DeleteObject();NewPen.CreatePen(PS_SOLID, 3, RGB(0, 0, 255));OldPen = pDC->SelectObject(&NewPen);pDC->LineTo(m_p[7].m_x, m_p[7].m_y);pDC->LineTo(m_p[4].m_x, m_p[4].m_y);NewPen.DeleteObject();NewPen.CreatePen(PS_SOLID, 3, RGB(0, 255, 255));OldPen = pDC->SelectObject(&NewPen);pDC->MoveTo(m_p[8].m_x, m_p[8].m_y);pDC->LineTo(m_p[10].m_x, m_p[10].m_y);NewPen.DeleteObject();NewPen.CreatePen(PS_SOLID, 3, RGB(255, 0, 255));OldPen = pDC->SelectObject(&NewPen);pDC->MoveTo(m_p[9].m_x, m_p[9].m_y);pDC->LineTo(m_p[11].m_x, m_p[11].m_y);pDC->SelectObject(OldPen);
}
测试效果
//平移
//缩放
//平移+旋转
//平移+错切 lambdax=0.5,lambday=0.5
//对称+平移