给出2或3个梯形(橙色)。每个梯形的至少一侧与另一个梯形相邻,形成一个简单的多边形。
矩形表示为四个点的列表,从左上角开始顺时针方向,例如
[
{x: 0, y: 0},
{x: 50, y: 0},
{x: 75, y: 30},
{x: 60, y: 30}
]
任务是制作一个多边形(绿色),表示为一个点列表:
[
{x: 0, y: 0},
{x: 50, y: 0},
{x: 75, y: 30},
{x: 60, y: 30},
{x: 60, y: 170}
…
{x: 0, y: 0}
]
答案 0 :(得分:1)
创建所有点的列表(为简单起见,下面的代码是静态分配的)
const int _max=128; // max number of points
int pnts=0; // actual number of points
double pnt[_max][2]; // points
// add points to pnt,pnts
为多边形创建结构(为简单起见,也是静态的)
_struct poly
{
int p[_max]; // index of points used
int n; // number of points
poly() { n=0; }
};
创建一个多边形列表(对于你的梯形)
(+/-)一些准确度
const int _maxp = 16; //最大多边形数 _poly poly [_maxp]; int polys = 0 //将梯形添加到poly,polys
现在只需合并所有可以合并在一起的东西(类似这样)
_poly o; // output merged polygon
_poly *p;
int i,j,k,a0,a1,b0,b1;
o=poly[0]; // start merging with first polygon
poly[0].n=0; // after merge mark it as empty
for (p=poly,i=0;i<polys;i++,p++)
if (p->n) // ignore empty polygons
for (a0=p->p[p->n-1],a1=p->p[0],j=0;j<p->n;j++,a0=a1,a1=p->p[j])
for (b0=o.p[o.n-1],b1=o.p[0],k=0;k<o.n;k++,b0=b1,b1=o.p[k])
{
if ((a0==b1)&&(a1==b0)) // if polygons share anti-parallel line then merge them
{
_poly t=o;
for (o.n=0;o.n<k; o.n++) o.p[o.n]=t.p[o.n];
for (i=j ;i<p->n;i++,o.n++) o.p[o.n]=p->p[i];
for (i=0 ;i<j ;i++,o.n++) o.p[o.n]=p->p[i];
for ( ;k<t.n;k++,o.n++) o.p[o.n]=t.p[k];
p->n=0; i=0; j=1; break; // mark used polygon as empty and restart from beginning
}
if ((a0==b0)&&(a1==b1)) // this is never true if all polygons have the same winding
{
// if not then just do merge also but in the oposite direction then above
}
}
注释
希望我没有在某个地方犯下一个愚蠢的错误(特别是在合并中),但我认为它显然足以看到背后的想法。
答案 1 :(得分:1)
由于我们按顺时针顺序在梯形上有所有点,让我们将它们视为有向边或“弧”的集合(连续点之间的箭头,包围)。
我们要排除的弧正好是多边形中的内部弧,它们都成对出现。即如果[a,b,c,d]是一个梯形,[d,c,x,y]是另一个,那么我的多边形应该是[a,b,c,x,y,d],它排除了这一对弧(c,d)和(d,c)。
您可以在线性时间内找到要排除的弧(通过哈希或邻接矩阵)。然后找到你的多边形只是按顺序将剩余的弧拼接在一起。
假设我们将点映射到他们的邻居。在上面的例子中,这看起来像: a->(b),b->(c),c->(d,x),d->(a,c),x->(y),y->(d )
排除一个坏弧对(两个方向的c到d)后,我们有: a->(b),b->(c),c->(x),d->(a),x->(y),y->(d),根据需要