三角形的平移、旋转
原理很简单:
平移
将图形对象从一个位置(x, y)移到另一个位置(x’,y’)的变换。
Tx= x’ -x,Ty= y’ -y称为平移距离。
平移变换公式为:
如下图所示:
旋转
旋转是以某个参考点为圆心,将对象上的各点(x, y)围绕圆心转动一个逆时针角度θ,变为新的坐标(x’,y’)的变换。当参考点为(0, 0)时,旋转的公式为:
如下图所示:
如果参考点不是(0, 0),而是任意一点(Xr, Yr),那么绕(Xr, Yr)点的旋转就需要
3个步骤:
其实原理大家都懂,不难。但是计算机大部分计算都是用的线性代数里面的矩阵运算,所以对于不熟悉线性代数的朋友就很困难了。对于图形学来说,矩阵计算不可避免,既直观又方便。
重点是理解矩阵的含义:矩阵其实是一种坐标系的转换
平移
起始坐标(x,y),变化后的坐标(x’,y’),x方向平移距离Tx,y方向平移距离Ty
公式如下:
那么用矩阵是怎么来表示呢?(看下图,先看着,一会用代码表示)
旋转
起始坐标(x,y),变化后的坐标(x’,y’),顺时针旋转θ
公式如下:
用矩阵表示
接着上代码:
首先是矩阵的定义及矩阵乘法,及头文件
#include "graphics.h"
#include <conio.h>
#include "windows.h"
#include <math.h>
#define pi 3.1415926;
struct matrix
{
float m[3][3];
}; //定义了矩阵结构体,用二维数组存储3×3矩阵
matrix operator*(matrix a,matrix b) //重载了乘法运算,矩阵乘法
{
matrix c={0};
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
for(int k=0;k<3;k++)
{
c.m[i][j]+=a.m[i][k]*b.m[k][j];
}
}
}
return c;
}
绘制三角形:
void triangle(float a[][3],COLORREF c)
{
DDA(a[0][0],a[0][1],a[1][0],a[1][1],c);
DDA(a[0][0],a[0][1],a[2][0],a[2][1],c);
DDA(a[1][0],a[1][1],a[2][0],a[2][1],c);
}
接着是平移和旋转的核心算法:
matrix translation(matrix a,float Tx,float Ty)//平移 矩阵a x,y方向的平移距离
{
matrix t={1,0,0,0,1,0,Tx,Ty,1};//该处矩阵对应之前那个图
matrix c=a;
c=c*t;
return c;
}
matrix rotate(matrix a,float angle,float x,float y)//旋转 矩阵a,角度,绕点(x,y)
{
float radian=angle/180*pi;//角度转弧度,因为C库里面的sin、cos函数,参数为弧度
matrix t={cos(radian),sin(radian),0,-sin(radian),cos(radian),0,0,0,1};//此处也同样是对应前面的图
a=translation(a,-x,-y);//对应上面旋转的步骤A
a=a*t;//步骤B
a=translation(a,x,y);//步骤C
return a;
}
然后就是主函数:
void main()
{
int gd=DETECT,gm; /*图形屏幕初始化*/
initgraph(&gd,&gm,"");
struct matrix a={100,100,1,100,200,1,200,200,1};//矩阵a存储三角形三个顶点
struct matrix c=a;
triangle(c.m,LIGHTBLUE);//绘制三角形
c=a;
c=translation(c,200,0);//平移
triangle(c.m,LIGHTBLUE);
c=a;
c=rotate(c,30,100,100);//旋转
triangle(c.m,LIGHTBLUE);
getch();
closegraph();
}
DDA直线算法请看这:https://blog.csdn.net/qq_41698119/article/details/101120707
最终效果图: