📄 suanfa.cpp
字号:
#include "stdafx.h"
#include "suanfa.h"
//在指定的pDC设备中,画多边形
bool CGraphics::DrawPloyon(CDC* pDC)
{
if(PointCount < 3)
return false;
//若多边形小于三个点则返回
pDC->MoveTo(Point[0]);
for(int i=1;i<PointCount;i++)
{
pDC->LineTo(Point[i]);
}
pDC->LineTo(Point[0]);
//在pDC中画出多边形
return true;
}
bool CGraphics::CutRect(CRect rect)
{
CPoint rectPoint[4];
rectPoint[0].x = rect.left;
rectPoint[0].y = rect.top;
rectPoint[1].x = rect.right;
rectPoint[1].y = rect.top;
rectPoint[3].x = rect.left;
rectPoint[3].y = rect.bottom;
rectPoint[2].x = rect.right;
rectPoint[2].y = rect.bottom;
//获取裁减矩形的四个点的坐标,第一个点为左上,第二个点为右上,第三个点为右下,第四个点为左下
int i;
CArray<CPoint,CPoint&> myArray;//裁减后,保存的多边形的依次各点的坐标
for(int rectNum=0;rectNum<4;rectNum++)
{
//对裁减矩形的四条边进行循环
for(i=0;i<PointCount;i++)
{
//对每条边进行循环
CPoint PointCross;
int beforeI=BeforeIndex(i),afterI=AfterIndex(i);
int afterrectNum = ((rectNum == 3)?0:rectNum+1);
//判断是否跟线段相交
if(InterCross(Point[beforeI],Point[i],rectPoint[rectNum],rectPoint[afterrectNum],PointCross))
{
if(PointCross==Point[i])
{
myArray.Add(Point[i]);//交点在线段顶点上,直接添加顶点坐标在保存多边形的数组中
}
else
if(PointCross==Point[beforeI])
{
if(IsInSquareRgn(rect,Point[i],rectNum))
myArray.Add(Point[i]);//判断是否可视,若是,则添加点坐标
}
else
{
myArray.Add(PointCross);//跟线段相交,但交点不在顶点上,添加交点坐标
if(IsInSquareRgn(rect,Point[i],rectNum))
myArray.Add(Point[i]);//判断是否可视,若是,则添加点坐标
}
}
else
if(IsInSquareRgn(rect,Point[i],rectNum))
myArray.Add(Point[i]);//线段不相交,但需判断是否可视,若是,则添加点坐标
}
PointCount=myArray.GetSize();
if(Point)
delete Point;
Point = new CPoint[PointCount];
for(i=0;i<PointCount;i++)
Point[i]=myArray.GetAt(i);//重新赋予点坐标的值
myArray.RemoveAll();
}
return true;
}
bool CGraphics::InterCross(CPoint objectP1,CPoint objectP2,CPoint scanP1,CPoint scanP2,CPoint& coordinate)
{
//objectP1、objectP2是一条线段的顶点坐标,而scanP1、scanP2是另一条线段的顶点坐标
if(objectP1 == objectP2)
return false;//若objectP1、objectP2相等,则构不成线段,退出
if(scanP1 == scanP2)
return false;//若scanP1、scanP2等,则构不成线段,退出
if( ( objectP1.y - objectP2.y ) * ( scanP1.x - scanP2.x )
== ( scanP1.y - scanP2.y ) * ( objectP1.x - objectP2.x))
{
//对斜率相等的情况下的处理
if((objectP1.y-objectP2.y)*(scanP1.x-objectP1.x)==(objectP1.x-objectP2.x)*(scanP1.y-objectP1.y))
{
//判断两条线段是不是同一条线段
coordinate=objectP2;
return true;
}
else
return false;
}
if(objectP1.x == objectP2.x)
{
//当第一条线段斜率不存在时,处理办法
double x,y;
x = objectP1.x;
y = (scanP1.y-scanP2.y)*1.0/(scanP1.x-scanP2.x)*(objectP1.x-scanP1.x)+scanP1.y;
y = (float)((int)(y+0.5));
if(((objectP1.y-y)*(y-objectP2.y)>=0) && ((objectP1.x-x)*(x-objectP2.x)>=0))
{
//判断交点是不是在该两条线段上
coordinate.x = objectP1.x;
coordinate.y = (int)(y+0.5);
return true;
}
return false;
}
else
{
if(scanP1.x == scanP2.x)
{
//当第二条线段斜率不存在时,处理办法
double x,y;
x = scanP1.x;
y = (objectP1.y-objectP2.y)*1.0/(objectP1.x-objectP2.x)*(scanP1.x-objectP1.x)+objectP1.y;
y = (float)((int)(y+0.5));
if(((objectP1.y-y)*(y-objectP2.y)>=0) && ((objectP1.x-x)*(x-objectP2.x)>=0))
{
//判断交点是不是在该两条线段上
coordinate.x = scanP1.x;
coordinate.y = (int)(y+0.5);
return true;
}
return false;
}
else
{
//两条线段斜率都存在时的处理办法
double k1,k2;
k1 = ( objectP1.y - objectP2.y ) * 1.0 / ( objectP1.x - objectP2.x);
k2 = ( scanP1.y - scanP2.y ) * 1.0 / ( scanP1.x - scanP2.x );
//k1,k2为计算的两线段的斜率
double x,y;
x = (scanP1.y-objectP1.y-k2*scanP1.x+k1*objectP1.x)/(k1-k2);
y = (k1*k2*scanP1.x-k1*k2*objectP1.x+k2*objectP1.y-k1*scanP1.y)/(k2-k1);
x=(float)((int)(x+0.5));
y = (float)((int)(y+0.5));
if(((objectP1.y-y)*(y-objectP2.y)>=0) && ((objectP1.x-x)*(x-objectP2.x)>=0))
{
//判断交点是不是在该两条线段上
coordinate.x = (int)(x+0.5);
coordinate.y = (int)(y+0.5);
return true;
}
return false;
}
}
return true;
}
bool CGraphics::IsInSquareRgn(CRect rect,CPoint Point,int flag)
{
//对多边形裁减时,判断线段端点是否在可视一侧,判断就是直接判断点坐标的关系
switch(flag)
{
case 0:
if(Point.y > rect.top)
return true;
else
return false;
break;
case 1:
if(Point.x < rect.right)
return true;
else
return false;
break;
case 2:
if(Point.y < rect.bottom)
return true;
else
return false;
break;
case 3:
if(Point.x > rect.left)
return true;
else
return false;
break;
default:
break;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -