这是2D计算几何的一个简单问题,我一直未能成功解决:
we have four points A, B, C, D defining a CONVEX QUADRILATERAL
(not a square or a rectangle!)
we know the (x, y) coordinates of each point.
有6个段连接2个点:
AB, AC, AD, BC, BD, CD
这些线段的一个交叉点将在图中形成一个点:两个对角线的交点。
对角线夫妇有3种可能:
[AB] and [CD]
[AC] and [BD]
[AD] and [BC]
(见下图)
我正在寻找一种简单的算法来查找当我改变A,B,C,D的(x,y)坐标时发生的3种可能情况中的哪一种
答案 0 :(得分:2)
实施例
不适用于凹几何体。
更好的解释(附图)
在这张图片中,∠DAB = ∠DAC + ∠BAC
。因此,∠DAC < ∠DAB
和∠BAC < ∠DAB
。
AC是共享的,是对角的。 BC是另一个对角线。
即。在所有情况下,两个小角度形成“大”角度,并且它们的共享侧将“大”角分成两个小角度。对于凸四边形中的单个顶点,只需要检查3个角度,这足以找到所有对角线。
矢量标准化。
归一化向量是长度为1.0
的向量。
要标准化矢量,请按因子1.0/length
进行缩放。长度可以用点积计算。
normalizedVector = scale(originalVector, 1/length(originalVector))
(注意这里长度为0的向量。)
length(vector) = sqrtf(dotProduct(vector, vector))
“缩放”向量将其与标量相乘。
答案 1 :(得分:1)
我能弄清楚的简单:
看看他们之间的关系。
Case 1: SAC>SAB>SAD,
Case 2: SAB>SAC>SAD,
Case 3: SAB>SAD>SAC.
考虑360度差异。
P.S。我不确定你是否关心角度> 4的四边形180.如果是,你必须另外考虑它们。
答案 2 :(得分:1)
提示: 我认为你要从定义凸包点和线开始。 Wiki-Graham Scan Alg.可用于确定参与创建凸包的线段。一旦确定了线段,就可以轻松找到对角线。使用链接中的示例,可以在数组中存储以下线段(按算法确定的顺序)(每对点定义一个线段):
P,A
A,B
B,D
D,P
从这个数组中,你可以立即得到对角点为P,B和A,D。
该算法不需要角度计算,也没有区域形状的假设。
答案 3 :(得分:1)
点{A,B,C,D}形成4个三角形:ABC,ABD,ACD和BCD。计算它们的方向产生一个4位二进制特征,它确定凸包的顺序如下:
signature key: "+" for counterclockwise, "-" for clockwise
A A A B
B B C C convex hull, in counterclockwise order:
C D D D
+ + + + quadrilateral ABCD
+ + + - triangle ABD (C is internal)
+ + - + triangle ABC (D is internal)
+ + - - quadrilateral ABDC
+ - + + triangle BCD (A is internal)
+ - + - (should not happen)
+ - - + quadrilateral ADBC
+ - - - triangle ADC (B is internal)
(inverting all signature bits reverses hull orientation)
- + + + triangle CDA (B is internal)
- + + - quadrilateral CBDA
- + - + (should not happen)
- + - - triangle DCB (A is internal)
- - + + quadrilateral CDBA
- - + - triangle CBA (D is internal)
- - - + triangle DBA (C is internal)
- - - - quadrilateral DCBA
您可以按如下方式计算任何给定三角形的方向(顺时针或逆时针):
struct Point {
float x, y;
Point(float xx,float yy):x(xx),y(yy){}
};
Point operator+(Point A, Point B) { return Point(A.x+B.x,A.y+B.y); }
Point operator-(Point A, Point B) { return Point(A.x-B.x,A.y-B.y); }
float orientation(Point A, Point B, Point C) {
Point AB = B - A;
Point AC = C - A;
return AB.x*AC.y - AB.y*AC.x; // 2-D equivalent to the 3-D cross-product
}
如果三角形ABC是逆时针,则函数orientation(A,B,C)
返回正值,如果是顺时针,则返回负值,如果是退化,则返回零。 (如果你的坐标系是左手而不是右手,那么顺时针方向是逆时针交换的,但这并不重要......)
答案 4 :(得分:0)
如果你的坐标是:
0,0
0,1
1,0
1,1
你可以认识到具有相同x和y坐标的那些形成对角线,而具有不同x和y坐标的那些形成对角线。
所以如果坐标是:
1,1
1,3
3,1
3,3
那么a,b处的字母,其中a = b形成一个,而a,b处的字母,其中a!= b形成一个,所以 1,1和3,3的字母是1,1,3和3,1也是如此。
请注意,这只适用于正方形。
另外,无论如何,你可以这样做:
你可以匹配不共享相同坐标的对。
代表
A--B
| |
C--D
你可以知道A和D是一对,因为A和C共用一个X坐标,而A和B共用一个Y坐标。
没有共同的坐标==对角线。 (以这种方式任何方形或矩形。)
希望这有帮助。