mfc 多边形裁剪算法
程序员文章站
2022-03-13 14:50:47
...
多边形裁剪
效果截图:
1.头文件定义:
enum Boundary{Left, Right, Bottom, Top};
int cj_line_x1;//裁剪直线时原直线的坐标
int cj_line_x2;
int cj_line_y1;
int cj_line_y2;
CPoint cj_win1;//裁剪窗口坐标,矩形窗口的对角坐标
CPoint cj_win2;
//多边形裁剪
int dbx_count;
CPoint ps[5];//这里以画五个顶点的多变形为例,而且不必初始化
以上定义的一定要在构造函数里初始化,不然会报错
具体实现:
//判断点在裁剪框内外
int CquhongjuanView::Inside(POINT p, Boundary b, POINT wMin, POINT wMax)
{
switch (b)
{
case Left:
if (p.x<wMin.x) return (false);
break;
case Right:
if (p.x>wMax.x) return (false);
break;
case Bottom:
if (p.y<wMin.y) return (false);
break;
case Top:
if (p.y>wMax.y) return (false);
break;
}
return true;
}/*Inside*/
/* 求相交的点 */
POINT CquhongjuanView::Intersect(POINT p1, POINT p2, Boundary b, POINT wMin, POINT wMax)
{
POINT iPt;
float m;
if (p1.x != p2.x) m = (p2.y - p1.y)*1.0 / (p2.x - p1.x);
switch (b) {
case Left:
iPt.x = wMin.x;
iPt.y = p2.y + (wMin.x - p2.x)*m;
break;
case Right:
iPt.x = wMax.x;
iPt.y = p2.y + (wMax.x - p2.x)*m;
break;
case Bottom:
iPt.y = wMin.y;
if (p1.x != p2.x)iPt.x = p2.x + (wMin.y - p2.y) / m;
else iPt.x = p2.x;
break;
case Top:
iPt.y = wMax.y;
if (p1.x != p2.x) iPt.x = p2.x + (wMax.y - p2.y) / m;
else iPt.x = p2.x;
break;
}
return iPt;
}/*Intersect*/
//按边裁剪
int Cquhongjuaniew::edgeCliper(Boundary b, POINT wMin, POINT wMax, POINT *pIn, int cnt, POINT *pOut) {
POINT s;
int i, Outcnt = 0;
s = pIn[0];
for (i = 1; i <= cnt; i++)
{
if (!Inside(s, b, wMin, wMax) && Inside(pIn[i], b, wMin, wMax))
{
pOut[Outcnt] = Intersect(s, pIn[i], b, wMin, wMax);
Outcnt++;
pOut[Outcnt] = pIn[i];
Outcnt++;
}
else if (Inside(s, b, wMin, wMax) && Inside(pIn[i], b, wMin, wMax))
{
pOut[Outcnt] = pIn[i];
Outcnt++;
}
else if (Inside(s, b, wMin, wMax) && (!Inside(pIn[i], b, wMin, wMax)))
{
pOut[Outcnt] = Intersect(s, pIn[i], b, wMin, wMax);
Outcnt++;
}
s = pIn[i];
}
return Outcnt;
}/*edgeCliper*/
/* 多边形裁剪 */
void CquhongjuanView::clipPolygon(CDC * pDC){
int i, cnt, Outcnt, b;
//多写了第一个点是为了使得最后一个点与第一个点连起来
POINT points[6] = { { ps[0].x,ps[0].y },{ ps[1].x,ps[1].y },{ ps[2].x,ps[2].y },{ ps[3].x,ps[3].y },
{ ps[4].x,ps[4].y },{ ps[0].x,ps[0].y} };
cnt = 5;
POINT pOut[20], pIn[20];
POINT wMin = { 100,100 }, wMax = { 300,300 };
for (i = 0; i < 4 * cnt; i++)
{
pIn[i].x = 0;
pIn[i].y = 0;
pOut[i].x = 0;
pOut[i].y = 0;
}
for (i = 0; i <= cnt; i++) pIn[i] = points[i];
for (b = 0; b < 4; b++)
{
Outcnt = edgeCliper(Boundary(b), wMin, wMax, pIn, cnt, pOut);
for (i = 0; i < Outcnt; i++)
pIn[i] = pOut[i];
pIn[Outcnt] = pOut[0];
cnt = Outcnt;
}
pDC->Rectangle(wMin.x, wMin.y, wMax.x, wMax.y);
pDC->Polygon(pOut, cnt);
return;
}/* clipPolygon */
/* 显示未裁剪的多边形和框 */
void CquhongjuanView::showUnclipPolygon(CDC * pDC){
POINT points[5] = { { ps[0].x,ps[0].y },{ ps[1].x,ps[1].y },{ ps[2].x,ps[2].y },{ ps[3].x,ps[3].y },
{ ps[4].x,ps[4].y } };
//POINT points[8];
POINT wMin = { 100,100 }, wMax = { 300,300 };
CBrush * pOldBrush = (CBrush *)pDC->SelectStockObject(NULL_BRUSH);
pDC->Rectangle(wMin.x, wMin.y, wMax.x, wMax.y);
pDC->Polygon(points, 5);
pDC->SelectObject(pOldBrush);
}
可能有些定义不明确,可以根据上下文语境推测,主要是这个做起来有点烦,就懒得写了,体谅一下
ps:mfc相关直线、圆、椭圆、多边形、多边形填充、裁剪直线可以关注我的博客
上一篇: 连通不规则多边形算法
下一篇: 物理系统与碰撞