给出了凸多边形和凸裁剪区域。任务是使用Sutherland-Hodgman算法修剪多边形边缘。输入为多边形的顶点形式(按顺时针顺序) 。
例子:
输入:多边形:(100,150),(200,250),(300,200)剪切区域:(150,150),(150,200),(200,200),(200,150)即正方形输出:(150,162)(150,200)(200 ,200)(200,174) 示例2输入:多边形:(100,150),(200,250),(300,200)剪切区域:(100,300),(300,300),(200,100)输出:(242、185)(166、166)(150、200)(200 ,250)(260,220)
算法概述:
Consider each edge e of clipping Area and do following:
a) Clip given polygon against e.
如何修剪剪切区域的边缘?
无限扩展(裁剪区域的)边缘以创建边界,并使用该边界对所有顶点进行裁剪。生成的新顶点列表将以顺时针方式传递到剪辑多边形的下一个边缘,直到使用完所有边缘为止。
对于给定多边形的任何给定边缘相对于当前剪切边缘e,有四种可能的情况。
- 两个顶点都在内部:仅将第二个顶点添加到输出列表中
- 第一个顶点在外部,第二个顶点在内部:边缘与剪切边界的交点和第二个顶点都添加到输出列表中
- 第一个顶点在内部,第二个顶点在外部:仅将边缘与剪辑边界的交点添加到输出列表中
- 两个顶点都在外部:没有将顶点添加到输出列表中
在实施算法之前,有两个子问题需要讨论:
决定一个点在剪切器多边形的内部还是外部
如果按顺时针方向给出了Clipper多边形的顶点,则位于Clipper边缘右侧的所有点都在该多边形内部。可以使用以下公式计算:
查找边缘与剪辑边界的交点
如果知道每条线的两个点(1,2&3,4),则可以使用以下公式计算它们的相交点:
// C++ program for implementing Sutherland–Hodgman
// algorithm for polygon clipping
#include
using namespace std;
const int MAX_POINTS = 20;
// Returns x-value of point of intersectipn of two
// lines
int x_intersect(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4)
{
int num = (x1*y2 - y1*x2) * (x3-x4) -
(x1-x2) * (x3*y4 - y3*x4);
int den = (x1-x2) * (y3-y4) - (y1-y2) * (x3-x4);
return num/den;
}
// Returns y-value of point of intersectipn of
// two lines
int y_intersect(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4)
{
int num = (x1*y2 - y1*x2) * (y3-y4) -
(y1-y2) * (x3*y4 - y3*x4);
int den = (x1-x2) * (y3-y4) - (y1-y2) * (x3-x4);
return num/den;
}
// This functions clips all the edges w.r.t one clip
// edge of clipping area
void clip(int poly_points[][2], int &poly_size,
int x1, int y1, int x2, int y2)
{
int new_points[MAX_POINTS][2], new_poly_size = 0;
// (ix,iy),(kx,ky) are the co-ordinate values of
// the points
for (int i = 0; i < poly_size; i++)
{
// i and k form a line in polygon
int k = (i+1) % poly_size;
int ix = poly_points[i][0], iy = poly_points[i][1];
int kx = poly_points[k][0], ky = poly_points[k][1];
// Calculating position of first point
// w.r.t. clipper line
int i_pos = (x2-x1) * (iy-y1) - (y2-y1) * (ix-x1);
// Calculating position of second point
// w.r.t. clipper line
int k_pos = (x2-x1) * (ky-y1) - (y2-y1) * (kx-x1);
// Case 1 : When both points are inside
if (i_pos < 0 && k_pos < 0)
{
//Only second point is added
new_points[new_poly_size][0] = kx;
new_points[new_poly_size][1] = ky;
new_poly_size++;
}
// Case 2: When only first point is outside
else if (i_pos >= 0 && k_pos < 0)
{
// Point of intersection with edge
// and the second point is added
new_points[new_poly_size][0] = x_intersect(x1,
y1, x2, y2, ix, iy, kx, ky);
new_points[new_poly_size][1] = y_intersect(x1,
y1, x2, y2, ix, iy, kx, ky);
new_poly_size++;
new_points[new_poly_size][0] = kx;
new_points[new_poly_size][1] = ky;
new_poly_size++;
}
// Case 3: When only second point is outside
else if (i_pos < 0 && k_pos >= 0)
{
//Only point of intersection with edge is added
new_points[new_poly_size][0] = x_intersect(x1,
y1, x2, y2, ix, iy, kx, ky);
new_points[new_poly_size][1] = y_intersect(x1,
y1, x2, y2, ix, iy, kx, ky);
new_poly_size++;
}
// Case 4: When both points are outside
else
{
//No points are added
}
}
// Copying new points into original array
// and changing the no. of vertices
poly_size = new_poly_size;
for (int i = 0; i < poly_size; i++)
{
poly_points[i][0] = new_points[i][0];
poly_points[i][1] = new_points[i][1];
}
}
// Implements Sutherland–Hodgman algorithm
void suthHodgClip(int poly_points[][2], int poly_size,
int clipper_points[][2], int clipper_size)
{
//i and k are two consecutive indexes
for (int i=0; i
输出:
(150, 162) (150, 200) (200, 200) (200, 174)
相关文章:
剪线|集合1(Cohen–Sutherland算法)
计算机图形学中的点裁剪算法