【图形学】实现二维几何变换

发布时间:2024年01月23日

二维点类

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
在这里插入图片描述

//对称+平移

在这里插入图片描述

文章来源:https://blog.csdn.net/m0_72895175/article/details/135758938
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。