二维图形几何变换(计算机图形学)

news/2024/10/23 4:51:03/

说明:本实验代码在vs2022下可正常运行,本实验适配于计算机图形学新版(VC++ MFC )第二版

1.实验目的

1)掌握3*3矩阵乘法运算的编程实现

2)掌握平移,比例,旋转三种基本二维几何变换矩阵生成

3)掌握相对于任意参考点的二维复合变换矩阵生成

2.实验要求

1)设计实现二维图形变换类,具有平移、比例、旋转二维几何变换功能,以及相对于任意参考点的二维复合变换功能;
2)将2.2节直线类所绘制的如图2-3所示的菱形线框,绕最上端A点匀速旋转,并要求相对于A点来回缩放。
3) 使用双缓冲机制进行图形绘制,避免运动闪烁,所有图形先绘制到用户自定的DC,绘制完成后再统一拷贝到屏幕DC。

3.实验步骤

本次实是对上一次直线扫描转换的代码进行增改,无需新建工程。

代码实现:

1)Line.h

#pragma once
class CP2
{
public:CP2();virtual~CP2();CP2(double, double);
public:double x;double y;double w;
};class CLine
{
public:CLine();virtual~CLine();void SetLineColor(COLORREF);void MoveTo(CP2);void MoveTo(double, double);void LineTo(CP2, CDC*);void LineTo(double, double, CDC*);
public:CP2 P0;CP2 P1;COLORREF clr;
};

2)Line.cpp

#include"pch.h"
#include"Line.h"
#include"math.h"
#define Round(d) int(floor(d+0.5))CP2::CP2()
{x = 0.0;y = 0.0;w = 1.0;
};CP2::~CP2()
{}CP2::CP2(double x, double y)
{this->x = x;this->y = y;this->w = 1;
};CLine::CLine()
{}CLine::~CLine()
{}void CLine::SetLineColor(COLORREF color)
{clr = color;
}
void CLine::MoveTo(CP2 p0)
{P0 = p0;
}
void CLine::MoveTo(double x, double y)
{P0.x = x;P0.y = y;
}
void CLine::LineTo(double x, double y, CDC* pDC)
{CP2 p;p.x = x;p.y = y;LineTo(p, pDC);
}
void CLine::LineTo(CP2 p1, CDC* pDC)
{P1 = p1;CP2 p, t;if (fabs(P0.x - P1.x) < 1e-6){if (P0.y > P1.y){t = P0; P0 = P1; P1 = t;}for (p = P0; p.y < P1.y; p.y++){pDC->SetPixelV(Round(p.x), Round(p.y), clr);}}else{double k, d;k = (P1.y - P0.y) / (P1.x - P0.x);if (k > 1.0){if (P0.y > P1.y){t = P0; P0 = P1; P1 = t;}d = 1 - 0.5 * k;for (p = P0; p.y < P1.y; p.y++){pDC->SetPixelV(Round(p.x), Round(p.y), clr);if (d >= 0){p.x++;d += 1 - k;}elsed += 1;}}if (0.0 <= k && k <= 1.0){if (P0.x > P1.x){t = P0; P0 = P1; P1 = t;}d = 0.5 - k;for (p = P0; p.x < P1.x; p.x++){pDC->SetPixelV(Round(p.x), Round(p.y), clr);if (d < 0){p.y++;d += 1 - k;}elsed -= k;}}if (k >= -1.0 && k < 0.0){if (P0.x > P1.x){t = P0; P0 = P1; P1 = t;}d = -0.5 - k;for (p = P0; p.x < P1.x; p.x++){pDC->SetPixelV(Round(p.x), Round(p.y), clr);if (d > 0){p.y--;d -= 1 + k;}elsed -= k;}}if (k < -1.0){if (P0.y > P1.y){t = P0; P0 = P1; P1 = t;}d = -1 - 0.5 * k;for (p = P0; p.y > P1.y; p.y--){pDC->SetPixelV(Round(p.x), Round(p.y), clr);if (d < 0){p.x++;d -= 1 + k;}elsed -= 1;}}}P0 = p1;
}

3)新建头文件CTrans2D.h

#pragma once
#include "Line.h"class CTrans2D // 二维几何转换
{
public:CTrans2D();virtual~CTrans2D();void SetPoints(CP2*, int);void Identity();void Translate(double, double); // 平移变换矩阵void Rotate(double); // 旋转变换矩阵void Scale(double, double); // 比例变换矩阵void RotatePoint(double, CP2); // 相对于任意点的旋转变换矩阵void ScalePoint(double, double, CP2); // 相对于任意点的比例变换矩阵
protected:void MultiMatrix(); // 矩阵相乘
public:double m_aT[3][3];CP2* m_pPoints;int m_iNum;
};

4)新建源文件CTrans2D.cpp

#include "pch.h"
#include"CTrans2D.h"
#include"math.h"
#define PI 3.14159
CTrans2D::CTrans2D()
{}
CTrans2D::~CTrans2D()
{}void CTrans2D::SetPoints(CP2 *p, int n) {m_pPoints = p;m_iNum = n;
}
void CTrans2D::Identity()//单位矩阵
{m_aT[0][0] = 1.0; m_aT[0][1] = 0.0; m_aT[0][2] = 0.0;m_aT[1][0] = 0.0; m_aT[1][1] = 1.0; m_aT[1][2] = 0.0;m_aT[2][0] = 0.0; m_aT[2][1] = 0.0; m_aT[2][2] = 1.0;
}
void CTrans2D::Translate(double tx, double ty)//平移变换矩阵
{Identity();m_aT[2][0] = tx;m_aT[2][1] = ty;MultiMatrix();
}
void CTrans2D::Rotate(double beta)//旋转变换矩阵
{Identity();double rad = beta*PI/180;m_aT[0][0] = cos(rad); m_aT[0][1] = sin(rad);m_aT[1][0] = -sin(rad); m_aT[1][1] = cos(rad);MultiMatrix();
}
void CTrans2D::Scale(double sx, double sy)//比例变换矩阵
{Identity();m_aT[0][0] = sx;m_aT[1][1] = sy;MultiMatrix();}
void  CTrans2D::RotatePoint(double beta, CP2 p)//相对于任意点的旋转变换矩阵
{Translate(-p.x, -p.y);Rotate(beta);Translate(p.x, p.y);
}
void CTrans2D::ScalePoint(double sx, double sy, CP2 p)//相对于任意点的整体比例变换矩阵
{Translate(-p.x, -p.y);Scale(sx, sy);Translate(p.x, p.y);//baotu
}
void CTrans2D::MultiMatrix()//矩阵相乘
{CP2 * PNew = new CP2[m_iNum];for (int i = 0; i < m_iNum; i++) {PNew[i] = m_pPoints[i];}for (int j = 0; j < m_iNum; j++){m_pPoints[j].x = PNew[j].x*m_aT[0][0] + PNew[j].y*m_aT[1][0] + PNew[j].w*m_aT[2][0];m_pPoints[j].y = PNew[j].x*m_aT[0][1] + PNew[j].y*m_aT[1][1] + PNew[j].w*m_aT[2][1];m_pPoints[j].w = PNew[j].x*m_aT[0][2] + PNew[j].y*m_aT[1][2] + PNew[j].w*m_aT[2][2];}delete []PNew;
}

5)TestView.cpp

只对TestView.cpp中的绘制函数进行修改,其他代码不变

需要导入头文件

#include "CTrans2D.h"
void CTestView::OnDraw(CDC* pDC)
{CTestDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;CRect rect;GetClientRect(&rect);pDC->SetMapMode(MM_ANISOTROPIC);pDC->SetWindowExt(rect.Width(), rect.Height());pDC->SetViewportExt(rect.Width(), -rect.Height());pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);/*rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);*/CDC MemDC; // 内存DCCBitmap NewBitmap, * pOldBitmap; // 内存中承载的临时位图MemDC.CreateCompatibleDC(pDC); // 建立与屏幕pDC兼容的MemDCNewBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()); // 创建兼容位图pOldBitmap = MemDC.SelectObject(&NewBitmap); // 将兼容位图选入MemDCMemDC.FillSolidRect(rect, pDC->GetBkColor()); // 按原来背景填充客户区,否则未黑色MemDC.SetMapMode(MM_ANISOTROPIC); // MemDC自定义坐标系与pDC相同MemDC.SetWindowExt(rect.Width(), rect.Height());MemDC.SetViewportExt(rect.Width(), -rect.Height());MemDC.SetViewportOrg(rect.Width() / 2, rect.Height() / 2);CLine* line = new CLine;line->SetLineColor(RGB(0, 0, 0));line->MoveTo(CP2(-rect.Width() / 2, 0));line->LineTo(CP2(rect.Width() / 2, 0), &MemDC);line->MoveTo(CP2(0, -rect.Height() / 2));line->LineTo(CP2(0, rect.Height() / 2), &MemDC);//绘制动态旋转int a = 200;CP2 points[4];points[0].x = 0, points[0].y = a;points[1].x = a, points[1].y = 0;points[2].x = 0, points[2].y = -a;points[3].x = -a, points[3].y = 0;//===================================================CP2 A(0, a);CTrans2D tans;tans.SetPoints(points, 4);static float s = 1.0;static float step = 0.01;if (s >= 2.0 || s <= 0.5)step = -step;s += step;tans.ScalePoint(s, s, A);//匀速逆时针旋转static float theta = 0.0;theta += 1.0;if (theta >= 360.0)theta = 0.0;tans.RotatePoint(theta, A);//====================================================//CP2 B(a, 0);//CP2 C(0, -a);//CP2 D(-a, 0);line->SetLineColor(RGB(255, 0, 0));//红色line->MoveTo(points[0]);line->LineTo(points[1], &MemDC);line->SetLineColor(RGB(0, 255, 0));//绿色line->LineTo(points[2], &MemDC);line->SetLineColor(RGB(0, 0, 255));//蓝色line->LineTo(points[3], &MemDC);line->SetLineColor(RGB(255, 255, 0));//黄色line->LineTo(points[0], &MemDC);delete line;//====================================================pDC->BitBlt(-rect.Width() / 2, -rect.Height() / 2, rect.Width(), rect.Height(), &MemDC, -rect.Width() / 2, -rect.Height() / 2, SRCCOPY);MemDC.SelectObject(pOldBitmap);NewBitmap.DeleteObject();Invalidate(FALSE);
}

实验结果:

e6a4f9515f2a49e08695c6a05482824b.png

 

 


http://www.ppmy.cn/news/574876.html

相关文章

计算机图形学 | 欢迎来到图形世界

计算机图形学 | 欢迎来到图形世界 计算机图形学 | 欢迎来到图形世界1.1 初识图形学计算机图形学相关学科发展历史 1.2 探秘图形应用与研究有趣的图形应用计算机辅助设计&#xff08;Computer-Aided Design&#xff09;&#xff1a;虚拟现实环境&#xff08;Virtual-Reality Env…

关于图形的绘制

import matplotlib.pyplot as plt #导入绘图第三方库 plt.plot([4,1,5,3]) plt.savefig(test1,dpi600) #存储图形文件 plt.savefig(../picture/test1,dpi600) plt.axis(equal) plt.show() import matplotlib.pyplot as plt #导入绘图第三方库 plt.plot([4,1,4,4,3,5,…

【XJTUSE计算机图形学】第三章 几何造型技术(1)——参数曲线和曲面

文章目录 【XJTUSE计算机图形学】第三章 几何造型技术(1)——参数曲线和曲面参数曲线和曲面曲线曲面参数表示非参数表示参数表示 曲线的基本概念插值、拟合和光顺(掌握概念)参数化概念参数化常用方法参数区间的规格化 参数曲线的代数和几何形式(了解一下)代数形式几何形式 连续…

【图形学】04 数学部分(四、放射变换)

文章目录 1、线性变换2、仿射变换3、张成空间4、对于齐次坐标的理解n、多边形重心的推论 1、线性变换 线性变换从几何直观有三个要点&#xff1a; 变换前是直线的&#xff0c;变换后依然是直线直线比例保持不变变换前是原点的&#xff0c;变换后依然是原点 比如说旋转&#x…

Matplotlib还能这么画!(附25个案例详细代码)

作者&#xff1a;zsx_yiyiyi 编辑&#xff1a;python大本营 大家好&#xff0c;今天分享给大家25个Matplotlib图的汇总&#xff0c;在数据分析和可视化中非常有用&#xff0c;文章较长&#xff0c;可以收藏下来慢慢练手。 # !pip install brewer2mpl import numpy as np import…

计算机基础:图形、图像相关知识笔记

1、图形、图像的基础知识 图形&#xff1a;由称为矢量的数学对象所定义的直线和曲线等组成。 图像&#xff1a;也称为栅格图像&#xff0c;由点阵图或位图图像、用像素来代表图像。每一个像素都被分配一个特点的位置和颜色值。 图形和图像之间在一定条件下可以互相转换&#xf…

点阵图(位图)与矢量图的区别

转自:http://www.eramx.com/article.php/97 计算机绘图分为点阵图(又称位图或栅格图像)和矢量图形两大类,认识他们的特色和差异,有助于创建、输入、输出编辑和应用数字图像。位图图像和矢量图形没有好坏之分,只是用途不同而已。因此,整合位图图像和矢量图形的优点,才是处…

【Python自然语言处理+tkinter图形化界面】实现智能医疗客服问答机器人实战(附源码、数据集、演示 超详细)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一、问答智能客服简介 QA问答是Question-and-Answer的缩写&#xff0c;根据用户提出的问题检索答案&#xff0c;并用用户可以理解的自然语言回答用户&#xff0c;问答型客服注重一问一答处理&#xff0c;侧重知识的推理。 …