#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();
}