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

二维点类

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

//对称+平移

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/640680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云原生 - 微信小程序 COS 对象存储图片缓存强制更新解决方案

问题描述 遇到一个这样的情况&#xff1a;在微信小程序里图片缓存十分麻烦&#xff0c;网上很多说在腾讯云里的 COS 存储对象服务里设置对应的图片缓存&#xff08;Header 头 Cache-Contorl&#xff09;&#xff0c;说实话真不好用&#xff0c;一会儿生效&#xff0c;一会儿没…

excel学习1

直接ctrl cctrl v会报错位移选择粘贴时用123那个数字粘贴而不是ctrl V 只要结果不要公式 上面复制的为数值这里是复制的公式他们两个不一样 这个方法太麻烦了直接用格式刷&#xff0c;选择一个区域一个单元格&#xff0c;不要选择多个一刷就出来了 第一个计算后向下拖就行了&…

FastDFS分布式文件存储

为什么会有分布式文件系统&#xff1f; 分布式文件系统是面对互联网的需求而产生。因为互联网时代要对海量数据进行存储。很显然靠简单的增加硬盘个数已经满足不了我们的要求。因为硬盘传输速度有限但是数据在急剧增长&#xff0c;另外我们还要要做好数据备份、数据安全等。采用…

Git的安装与配置

目录 前言 Linux-centos&#xff1a;下安装 Linux_ubuntu下安装 创建Git本地仓库 配置用户名和Email 前言 Git是一种版本控制器&#xff0c;能够让我们了解一个文件的历史&#xff0c;以及它的发展过程。通俗的将就是可以记录一个工程的每一次改动和版本迭代的一个管理系统…

【vscode】6、调试 shell

文章目录 经常在 IDE 下使用 高级语言后&#xff0c;往往并不习惯 shell 编程&#xff0c;因为没有酷炫的界面。但现在 vscode 可以很方便的调试 shell 脚本。 配置方法如下&#xff1a; vscode 下载 Bash Debug 插件 mac 升级 bash 版本&#xff08;因为此 vscode 插件需要 b…

蓝桥杯重要知识点和赛题直通车

<蓝桥杯软件赛>零基础备赛20周 第 1周(2023-10-23): 蓝桥杯软件赛介绍官方链接零基础能得奖吗&#xff1f; 第 2周(2023-10-30): 常考知识点蓝桥杯怎么判题备赛计划 第 3周(2023-11-06): 填空题&#xff08;分数少但越来越不好做&#xff09; 第 4周(2023-11-13): &#…

更改wpf原始默认按钮的样式

样式 代码 <Window x:Class"WpfApp4.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008…

141基于matlab的齿轮系统非线性动力学特性分析

基于matlab的齿轮系统非线性动力学特性分析&#xff0c;综合考虑齿侧间隙、时变啮合刚度、综合啮合误差等因素下&#xff0c;参数阻尼比变化调节下&#xff0c;输出位移、相图、载荷、频率幅值结果。程序已调通&#xff0c;可直接运行。 141 matlab齿轮非线性动力学 (xiaohongs…

【C++】多项式输出

记录一下这个WA了三遍才AC的题......QAQ 题目描述 一元 n 次多项式可用如下的表达式表示&#xff1a; 其中&#xff0c;aixi称为 i 次项&#xff0c;ai 称为 i 次项的系数。给出一个一元多项式各项的次数和系数&#xff0c;请按照如下规定的格式要求输出该多项式&#xff1a; f…

使用VSCode开发 Python虚拟环境配置说明

这里给大家介绍下怎么配置VSCode的环境来开发Python。 介绍&#xff1a; VSCode是一款由Microsoft开发的免费、开源的代码编辑器。它具有许多优势&#xff0c;使其成为许多开发者喜爱的工具之一。以下是一些VSCode的主要优势&#xff1a; 轻量且快速启动&#xff1a; VSCode是…

每日一题——LeetCode1299.将每个元素替换为右侧最大元素

方法一 个人方法&#xff1a; 题目意思就是求在i1;i的循环条件下&#xff0c;arr[i]-arr[arr.length-1]的最大值分别为多少&#xff0c;最后一项默认为-1 用slice方法可以每次把数组第一位去除&#xff0c;得到求最大值的目标数组 Math的max方法可以直接返回数组里的最大值 …

基于yolov5-master和pyqt5的森林火灾监测软件

文章目录 项目背景效果演示一、实现思路① 算法原理② 程序流程图 二、系统设计与实现三、模型评估与优化 项目背景 火灾作为威胁人类生命生产安全的隐患之一&#xff0c;一直是人们关注的重点。传统的火灾监测装置根据温度来检测火灾&#xff0c;不仅灵敏度差&#xff0c;而且…

数据结构课程设计 仓储管理系统

仓储管理系统 【基本功能】 把货品信息表抽象成一个线性表&#xff0c;货品信息&#xff08;包括ID、货品名、定价、数量等&#xff09;作为线性表的一个元素&#xff0c;实现&#xff1a;按ID、货品名分别查找某货品信息&#xff08;包括ID、货品名、定价、数量等&#xff0…

C++版QT:电子时钟

digiclock.h #ifndef DIGICLOCK_H #define DIGICLOCK_H ​ #include <QLCDNumber> ​ class DigiClock : public QLCDNumber {Q_OBJECT public:DigiClock(QWidget* parent 0);void mousePressEvent(QMouseEvent*);void mouseMoveEvent(QMouseEvent*); public slots:voi…

JVM常量池详解

欢迎大家关注我的微信公众号&#xff1a; 目录 Class常量池与运行时常量池 字符串常量池 字符串常量池的设计思想 三种字符串操作(Jdk1.7 及以上版本) 字符串常量池位置 字符串常量池设计原理 String常量池问题的几个例子 八种基本类型的包装类和对象池 Class常量…

防范水坑攻击:了解原理、类型与措施

水坑攻击是一种常见的网络攻击方式&#xff0c;它利用了人类在互联网上的行为习惯&#xff0c;诱导用户访问恶意网站或下载恶意软件&#xff0c;从而获取用户的个人信息或控制用户的计算机系统。本文将介绍水坑攻击的原理、类型和防范措施。 一、水坑攻击的原理 水坑攻击&…

Cyber RT 服务通信

场景&#xff1a; 用户乘坐无人出租车过程中&#xff0c;可能临时需要切换目的地&#xff0c;用户可以通过车机系统完成修改&#xff0c;路径规划模块需要根据新的目的地信息重新规划路径&#xff0c;并反馈修正后的结果给用户&#xff0c;那么用户的修正请求数据与修正结果是如…

使用STM32的SPI接口实现与外部传感器的数据交互

一、引言 外部传感器是嵌入式系统中常用的外设&#xff0c;用于检测环境参数、采集数据等。通过STM32微控制器的SPI接口&#xff0c;可以与外部传感器进行数据交互&#xff0c;从而实现数据的采集和控制。本文将介绍如何使用STM32的SPI接口实现与外部传感器的数据交互&#xff…

常用芯片学习——HC245芯片

HC245三态输出八路总线收发器 使用说明 这些八路总线收发器专为数据总线之间的异步双向通信而设计。控制功能实现可更大限度地减少外部时序要求。根据方向控制 (DIR) 输入上的逻辑电平&#xff0c;此类器件将数据从 A 总线发送至 B 总线&#xff0c;或者将数据从 B 总线发送至…

Windows安装Anaconda教程

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十八&#xff09;——Windows安装Anaconda教程 本文是我实践后写的&#xff0c;无脑跟随安装即可 在我看来&#xff0c;Anaconda的图标如同一只灵蛇咬住了自己的尾巴&#xff0c;优美而神秘。 全称&…