答案 0 :(得分:0)
求解每个线对的线性方程组
y = m[i] * x + b[i]
y = m[j] * x + b[j]
其中m [i],b [i]是第i行的系数,并且是交叉的get(x,y)。
如果恰好有6个交点(没有平行线,没有退化),那么每一行都有三个交叉点。两个交叉点是"外部"而一个(中间)是"内部",所以有三个内部和三个外部点。
似乎凸四边形总是包含所有三个内点,所以我们可以分离内点,得到相应的第四点。
例如,如果行被指定为A,B,C,D,并且交叉点AB,AC,CD在内部,则第四个点是交叉点BD(B和D在交叉点列表中是唯一的)
P.S。请注意,行方程式y=mx+b
不适用于所有可能的行(不适用于垂直行),因此最好使用A*x + B*y + C = 0
或其他NSSplitViewController
。
答案 1 :(得分:0)
First Concave QUAD:
第6个交叉点也应该在1)
我忘了把它画在那里。
计算所有交叉点并将它们与行配对
l1: p2,p5,p6
l2: p1,p4,p6
l3: p1,p2,p3
l4: p3,p4,p5
l
表示行,p
表示交叉点
确定点是仅边缘还是中间
所以中间点是,如果你从它所属的线的每一侧得到另一个点。换句话说,如果将点转换为其参数位置(或距某个起点的距离),则中间点位于其他两个点距离之间。交叉点计算时直接获得的参数/距离,但如果不相交,则可以使用:
t(p) = dot(p-A,B-A)
其中A,B
是行终点,p是查询的交叉点,t(p)
是与A
的标量“距离”。
因此,找出哪些点只是边e
,哪些是中m
:
l1: e2,e5,m6
l2: e1,e4,m6
l3: e1,m2,e3
l4: e3,m4,e5
现在如果任何一个点至少有一个中间然后它是部分中间,如果它只是边缘那么它是边缘而如果它只是中间那么它是中间的:
edge: p1,p3,p5
partial: p2,p4
middle: p6
构建多边形
所以我们必须使用边缘点。我们跳过的部分点(因为它们位于已使用的线上),最后我们也使用中间点。我们知道我们的多边形将是:
(p1,p3,p5) + (p6)
现在我们需要找到凹中点p6
的位置。有3种组合:
e1,m6,e3,e5
e1,e3,m6,e5
e1,e3,e5,m6
我们知道m6
属于l1,l2
而l1,l2
也有p2,p5,p1,p4
仅来自边缘点:e1,e5
所以m6
将放在他们之间,所以正确的解决方案是:
e1,e3,e5,m6
现在凸出QUAD:
如果我们利用#1,#2 然后形成凸四边形,我们必须使用中间和部分中间点并选择一个纯边缘点。选择不属于具有纯中点的线的那个。所以我们必须使用:
(p2,p4) + (m6) + one_from(e1,e3,e5)
m6
不属于l3,l4
所以我们需要找到属于e3
的边缘,所以
(p2,p4) + (m6) + (e3)
现在我们必须找出订单。中点和边缘点不会靠近自己,所以你有两个解决方案:
p2,m6,p4,e3
p2,e3,p4,m6
两者都是正确的它们只是相反(不同的多边形缠绕规则),因此您可以根据任意两个相邻顶点的叉积的z
坐标选择所需的那个。