假设我有4个点(它们是2维),它们彼此不同,并且我想知道它们是否形成正方形。怎么做?(让过程尽可能简单。)
假设我有4个点(它们是2维),它们彼此不同,并且我想知道它们是否形成正方形。怎么做?(让过程尽可能简单。)
Answers:
假设正方形可以相对于已有的坐标系旋转,则不能依赖于四个点中X和Y值的重复。
您可以做的是计算四个点之间的距离。如果您发现以下情况成立,那么您将得到一个正方形:
有两个点,比如说A和C,它们彼此之间的距离为x;还有另外两个点,比如说B和D,它们之间也是彼此的距离x。
每个点{A,B,C,D}与未x的两个点之间的距离相等。即:如果A 与C距离x,那么它将与B和D距离z。
顺便说一句,距离z必须为SQRT((x ^ 2)/ 2),但是您无需确认这一点。如果条件1和2为真,则您有一个正方形。 注意:有些人担心平方根的效率低下。我并不是说您应该进行此计算,我只是说,如果您进行了计算,您将得到可预测的结果!
您要做的最起码的工作是选择一个点(例如A)并计算到其他三个点的距离。如果您发现一个点的A是x,另外两个点的z是z,那么您只需要检查其他两个点是否相对即可。如果它们彼此也是x,则您有一个正方形。即:
由于AB = AD,请检查BD:
只是要确保,您需要检查另一面:BC和CD。
由于AC = BD,并且AB = AD = BC = CD,因此,这是一个正方形。
在此过程中,如果找到两个以上的不同边距,则该图形不能是正方形,因此可以停止查找。
工作示例实施
我已经在jsfiddle上创建了一个工作示例(请参阅此处)。在对算法的解释中,我使用了任意点A,B,C和D。为了遍历示例,这些任意点碰巧是按一定顺序排列的。即使这些点的顺序不同,该算法也可以工作,但是,如果这些点的顺序不同,则该示例不一定有效。
感谢: meshuai,Blrfl,MSalters和Bart van Ingen Schenau提出的有益意见,以改善此答案。
选择四个点中的三个。
通过检查点之间的三个向量之一是否等于旋转90度的另一个向量,找出它是否为等腰三角形。
如果是这样,则通过向量相加来计算第四点,并将其与给定的第四点进行比较。
请注意,这不需要昂贵的平方根,甚至不需要乘法。
sqrt
除非至关重要,否则不要使用!您无需将整数计算降级为FP ...更不用说降低FP计算的精度了。
我认为最简单的解决方案如下:
首先,计算这四个点的中心: center = (A + B + C + D)/4
然后计算向量A - center
。让它成为v := (x,y)
令v2
向量v
旋转90度:v2 := (-y, x)
现在,其他的点应该是center - v
,center + v2
和center - v2
。
此解决方案的优点是您根本不必使用平方根。
抱歉,某些答案不适用。
对于这种情况,您测量了3条边(假设AB,AC和AD),发现两条边具有相同的大小(例如AC和AD),而一条边更大(例如AB)。然后,您将测量CD以查看其大小是否与AB相同,然后您会发现它的大小。可能没有正方形,而是下面的图片,这使它成为错误的解决方案。
然后尝试其他解决方案:至少测量一次所有距离:AB,AC,AD,BC,BD,CD。然后,您发现那时的4个相等,而其他2个也相等。但是您可能只有下面的图片:
因此,尽管获得了很高的评价,但这些答案还是不正确的。
一种可能的解决方案:如果两个相等的度量未连接同一点。因此:如果AB和CD长度相同,则所有其他组合(AC,AD,BC,BD)也相等,那么您就有一个平方。如果同一点的长度最大(AB和AC最大,其他所有都相等),则上面的图片之一。
令这四个点具有坐标向量a,b,c,d。
然后让我们称它们的差异为w =(ad),x =(ba),y =(cb),z =(dc)。
如果可以从a旋转90度来创建w,则w与a正交。在数学上,二维空间中的90度旋转矩阵是((0,-1),(1,0)。因此,w是否为90度旋转的条件导致
(w_1 == -x_2和w_2 == x_1)
如果成立,则需要检查w == -y和x == -z,或者
((w_1 == -y_1和w_2 == -y_2)和(x_1 == -z_1和x_2 == -z_2))
如果这三个关系成立,则a,b,c,d会构成一个定向的正方形。
这里有一些很好的答案,但是这个问题要求最简单的方法。我快速思考了一下,这就是我会做的。
您可以判断四个点是否代表一个正方形(即使旋转),也可以找到四个点的平均值。
R = (A+B+C+D)/4
获得平均值后,所有四个点的每个点与平均值之间的距离必须相同。
if(dist(R,A) == dist(R,B) == dist(R,C) == dist(R,D) then
print "Is Square"
else
print "Is Not Square"
编辑:
我的错。那只会告诉您形状点是否在圆上。如果还检查点之间的距离,则它必须是正方形。
if(dist(R,A) == dist(R,B) == dist(R,C) == dist(R,D) AND
(dist(A,B) == dist(B,C) == dist(C,D) == dist(A,D) then
print "Is Square"
else
print "Is Not Square"
这假定点A,B,C,D不交叉(因为具有有效的缠绕顺序)。
根据标准集,这不是一个答案,但是我希望这会有所帮助:
[从下面的链接复制,因此您不必打开链接] Python 76个字符
def S(A):c=sum(A)/4.0;return set(A)==set((A[0]-c)*1j**i+c for i in range(4))
函数S将复数列表作为其输入(A)。如果我们知道正方形的中心和一个角,则可以通过围绕中心点(c)旋转角90,180和270度来重建正方形。在复平面上,通过将点乘以i绕原点旋转90度。如果我们的原始形状和重建的正方形具有相同的点,那么它一定是正方形。
摘自: 确定4个点是否形成正方形
我说,如果您喜欢答案,请花点时间感谢此人,或在该页面上投票给他的答案。
我认为您可以通过简单的加减运算来找到最小值/最大值。字词(与其他人的图匹配):
如果4个点仅共享2个x值和2个y值,则您有一个水平平方。
否则,如果您的点满足以下条件,则您有一个正方形:
说明:线段AC和BD应该在它们的中点相交。因此(Ax + Cx)/ 2是AC的中点,而(Bx + Dx)/ 2是BD的中点。将此方程的每一边乘以2,得到我的第一个方程。对于Y值,第二个方程式是相同的。菱形(菱形)将满足这些属性,因此您需要检查边是否相等-宽度是否与高度相同。那是第三个方程式。
基本想法(这回答了我是否正在贡献新的东西的问题,当我单击以提供答案时,该问题被机器人问到了):
我在R中的解决方案如下所示。我假设恰好有四个点,并且根据问题陈述,已经确定了这些点是唯一的。
sumsq <- function(x) sum(x^2)
quadrances.xy <- function(xy) vapply(
as.data.frame(t(diff(xy)), optional=T), sumsq, 1)
观看诺曼·怀德伯格(Norman Wildberger)的作品,尤其是他的YouTube视频(真实的鱼类,真实的数字,真实的工作等)和他的《神的比例》一书,其中讨论了“四面楚歌”。
xy
指的是由R的接受一种基质的plot
,points
和lines
功能。
应用as.data.frame
是使R按列进行操作的一种技巧。
该optional=T
子句消除了无论如何都不会使用的名称。
quadrances.xy..i2. <- function(xy, i2) vapply(
as.data.frame(i2, optional=T),
function(k) quadrances.xy(m[k,]),
1)
此函数用于计算指定点之间的象限,其中点对由i2
参数指定。该i2
符号指的是一个索引矩阵,每个索引具有一列,每列具有2个元素(该combn
函数返回的同类矩阵)。
quadrance.every.xy <- function(xy, .which=combn(nrow(xy), 2))
quadrances.xy..i2.(xy, .which)
的.which
是作为一个参数只是将其暴露在formals
并试图与之通信是怎么回事。
is.square.xy <- function(xy) {
qq <- sort(quadrance.every.xy(xy))
all(qq[2:4] == qq[1]) && # ALL SIDES (SHORT QUADRANCES) EQUAL
qq[5] == qq[6] # ALL DIAGONALS (LONG QUADRANCES) EQUAL
}
我说“简单”不包含多行功能。您必须原谅此两行功能。
xy <- t(matrix(c(3,0, 7,3, 4,7, 0,4), ncol=4))
xy
# [,1] [,2]
# [1,] 3 0
# [2,] 7 3
# [3,] 4 7
# [4,] 0 4
is.square.xy(xy)
# [1] TRUE
请注意,除了关于这四个要点的问题之外,前四个功能本身就很有用。
假设四个点A =(ax,ay),B =(bx,by),C =(cx,cy),D =(dx,dy),它们形成了一个逆时针方向的正方形点。通过将bx,cx和dx减去ax,然后将by,cy和dy减去ay,设置ax = ay = 0,移动点,使A处于(0,0)。
如果这些点按逆时针顺序恰好是正方形的角,则我们应具有(cx,cy)=(bx-by,bx + by)和(dx,dy)=(-by,bx)。因此,我们计算了从C和D到应到达的平方距离:errC =(cx-bx + by)^ 2 +(cy-bx-by)^ 2,而errD =(dx + by)^ 2 +(dy-bx)^ 2。我们将它们相加,然后除以(bx ^ 2 +除^ 2),得到err =(errC + errD)/(bx ^ 2 +除^ 2)。如果是完美的正方形,则结果err将为0;如果几乎是正方形,则结果为err;如果我们平移,缩放或旋转正方形的点,则该数字将保持不变,但舍入误差除外。
但是我们不知道顺序。我们可以找出哪个点是C,因为它离A远:计算distB = bx ^ 2 + by ^ 2,distD = dx ^ 2 + dy ^ 2。如果distD≥1.5 distB,则交换C和D;如果distB≥1.5 distD,则我们交换C和B。现在C是正确的。我们还可以找出哪些点是B和D:如果我们猜错了哪一个是B而哪一个是D,则我们的计算会将D放到完全错误的位置。所以如果errD≥(bx ^ 2 + by ^ 2),那么我们交换B和D。
摘要:
如果我们知道点的顺序,显然可以简化。