对称算法(计算机图形学)

#include<graphics.h>
#include<conio.h>
#include<iostream>
using namespace std;


class CPoint
{
	public:
	int x;
	int y;

	CPoint(){}

	CPoint(int x1,int y1)
	{
		x=x1;
		y=y1;
	}

	static CPoint ZeroMoveToXY(CPoint p, CPoint XY);//原始坐标向屏幕坐标XY的平移
	static CPoint ToZero(CPoint p);//关于原点对称
	static CPoint XYMoveToZero(CPoint p, CPoint XY);//XY坐标向屏幕坐标的平移
	static CPoint Charge_AllLine(CPoint p, CPoint line_start, CPoint line_end);//关于Ax+By+C = 0对称
};

//原始坐标向屏幕坐标XY的平移:p.x->(p.x-XY.x)  p.y->(p.y-XY.y)
CPoint CPoint::ZeroMoveToXY(CPoint p, CPoint XY)
{
	CPoint result;
	int change[3][3] = {{1,0,0},{0,1,0},{-XY.x,-XY.y,1}};//平移矩阵
	int p1[3] = {0,0,0};

	for (int j = 0;j < 3;j++)
	{
	   p1[j]=p.x * change[0][j] + p.y * change[1][j] + change[2][j];
	}

	result.x = p1[0];
	result.y = p1[1];

	return result;
}


//关于原点对称:p.x->p.-x   p.y->p.-y
CPoint CPoint::ToZero(CPoint p)
{
	CPoint result;
	int change[3][3] = {{-1,0,0},{0,-1,0},{0,0,1}};
	int p1[3] = {0,0,0};

	for (int j = 0;j < 3;j++)
	{
    	p1[j]=p.x * change[0][j] + p.y * change[1][j] + change[2][j];
	}

	result.x = p1[0];
	result.y = p1[1];

	return result;
}

//XY坐标向屏幕坐标的平移:p.x->(p.x+XY.x)  p.y->(p.y+XY.y)
CPoint CPoint::XYMoveToZero(CPoint p, CPoint XY)
{
	CPoint result;
	int change[3][3] = {{1,0,0},{0,1,0},{XY.x,XY.y,1}};
	int p1[3] = {0,0,0};

	for (int j = 0;j < 3;j++)
	{
	   p1[j]=p.x * change[0][j] + p.y * change[1][j] + change[2][j];
	}

	result.x = p1[0];
	result.y = p1[1];

	return result;
}

//关于直线Ax+By+C = 0对称
CPoint CPoint::Charge_AllLine(CPoint p, CPoint line_start, CPoint line_end) 
{
	double A,B,C;
	if(line_start.x == line_end.x)
	{
	    A = 1;B = 0;C = -line_start.x;
	}
	else if(line_start.y == line_end.y)
	{
     	A = 0;B = 1;C = -line_start.y;
	}
	else
	{
		A = line_end.y - line_start.y;
		B = -(line_end.x - line_start.x);
		C = -line_start.x*(line_end.y-line_start.y)+line_start.y*(line_end.x - line_start.x);
	}

	CPoint result;

	float Y_f = (A*A*p.y - A*B*p.x - B*C)/(B*B+A*A);
	float X_f = (B*B*p.x - A*B*p.y - A*C)/(B*B+A*A);

	CPoint xy,m1,m2;//xy为(经过点p且垂直于直线Ax+By+C=0的直线)与(直线Ax+By+C=0)的交点
	xy.x=X_f;
	xy.y=Y_f;

	m1 = CPoint::ZeroMoveToXY(p, xy);//原始坐标向屏幕坐标XY的平移,p.x->(p.x-XY.x)  p.y->(p.y-XY.y)
	m2 = CPoint::ToZero(m1);//关于原点对称,(p.x-XY.x)->(XY.x-p.x)   (p.y-XY.y)->(XY.y-p.y)
	result = XYMoveToZero(m2, xy);//XY坐标向屏幕坐标的平移,(XY.x-p.x)->(XY.x-p.x+XY.x)  (XY.y-p.y)->(XY.y-p.y+XY.y)

	return result;
}

// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)
void DisplayLine(int x1, int y1, int x2, int y2, int color)
{
	int x = x1, y = y1;
	int a = y1 - y2, b = x2 - x1;
	int cx = (b >= 0 ? 1 : (b = -b, -1));
	int cy = (a <= 0 ? 1 : (a = -a, -1));

	putpixel(x, y, color);

	int d, d1, d2;
	if (-a <= b)		// 斜率绝对值 <= 1
	{
		d = 2 * a + b;
		d1 = 2 * a;
		d2 = 2 * (a + b);
		while(x != x2)
		{
			if (d < 0)
				y += cy, d += d2;
			else
				d += d1;
			x += cx;
			putpixel(x, y, color);
		}
	}
	else				// 斜率绝对值 > 1
	{
		d = 2 * b + a; 
		d1 = 2 * b;
		d2 = 2 * (a + b);
		while(y != y2) 
		{ 
			if(d < 0)
				d += d1; 
			else 
				x += cx, d += d2; 
			y += cy; 
			putpixel(x, y, color);
		} 
	}
}

//画正方形
void DisplayRec(int x1,int y1,int x2,int y2,int color){
    DisplayLine(x1-50,y1,x2+50,y1,color);
	DisplayLine(x2,y1-50,x2,y2+50,color);
	DisplayLine(x2+50,y2,x1-50,y2,color);
	DisplayLine(x1,y2+50,x1,y1-50,color);
}

//画三角形
void DisplayTriangle(){
   DisplayLine(100,100,300,125,RED);
   DisplayLine(100,100,200,225,RED);
   DisplayLine(300,125,200,225,RED);
}

//显示图形
void Display()
{
	int n=3,x,y,i;

	//画三角形
	CPoint *p=new CPoint[3];
	p[0].x=100;p[0].y=100;
	p[1].x=300;p[1].y=125;
	p[2].x=200;p[2].y=225;

	
	//画直线
	CPoint *p2=new CPoint[2];
	p2[0].x=350;p2[0].y=60;
	p2[1].x=180;p2[1].y=400;
	//DisplayLine(350,60,180,400,GREEN);

	int gdriver=DETECT, gmode;

	initgraph(&gdriver,&gmode,"");//根据测试结果初始化图形界面

	//画多边形
	for(i=1;i<n;i++)
	{
		DisplayLine(p[i-1].x,p[i-1].y,p[i].x,p[i].y,RED);

		if(i==n-1)
		{
	        DisplayLine(p[n-1].x,p[n-1].y,p[0].x,p[0].y,RED);
		}
	}

       //画直线    
	DisplayLine(p2[0].x,p2[0].y,p2[1].x,p2[1].y,GREEN);
	
	//顶点按矩阵复合变换
	for(i=0;i<n;i++)
	{	
		p[i]=CPoint::Charge_AllLine(p[i], p2[0], p2[1]);
	}

	//画对称后的多边形
    for(i=1;i<n;i++)
	{
		DisplayLine(p[i-1].x,p[i-1].y,p[i].x,p[i].y,RED);

		if(i==n-1)
		{
	        DisplayLine(p[n-1].x,p[n-1].y,p[0].x,p[0].y,RED);
		}
	}

}



// 主函数
void main()
{
	Display();
	
	// 按任意键退出
	getch();
	closegraph();
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值