4つのポイントが正方形を形成しているかどうかを確認する方法は?


35

互いに異なる4つのポイント(2次元)があり、それらが正方形を形成しているかどうかを知りたいと仮定します。どうやってするの?(プロセスを可能な限りシンプルにします。)


3
回転した正方形を考慮する必要があると思いますか?
マーティンピーターズ

ポイントの順序に関する情報はありますか?すなわち、2つの点が隣接しているか、対角線を形成しているかを確認できますか?(この情報は、プロセスを簡素化するために使用できます)
ダニエルB

1
@DanielBその他の情報はありません。私が白い紙を持っており、その上にランダムに4ポイントを描くように。次に、正方形を形成するかどうかを知りたいです。
MarshalSHI

5
特に、ポイントが浮動小数点数として表されている場合、以下に示す比較のいずれかに「許容」の感覚を含めると便利です。人間が「十分に近い」と考える場合でも、浮動小数点演算の結果の正確な等価性チェックは失敗する可能性があります。
ステファンA.テレ

これは宿題の質問のような匂いがします。それに何か問題があるわけではありません。:/ whathaveyoutried.com
ジムG.

回答:


65

正方形が任意の座標系に対して回転する可能性があると仮定すると、4つのポイントでX値とY値が繰り返されることに依存することはできません。

できることは、4つのポイントのそれぞれの間の距離を計算することです。次のことが当てはまる場合、正方形があります。

  1. 互いに距離xであるAとC などの2つのポイントと、互いに距離xでもあるBとDといった2つのポイントがあります。

  2. 各ポイント{A、B、C、D}は、x離れていない2つのポイントから等しい距離です。つまり、AがCからx離れている場合、BとDの両方からz離れています。

ちなみに、距離zはSQRT((x ^ 2)/ 2)である必要がありますが、これを確認する必要はありません。条件1と2が真の場合、正方形があります。 注:平方根の非効率性を懸念する人もいます。この計算行うべきだとは言いませんでした。そうすると、予測可能な結果が得られると言いました。

正方形ルールの図

最低限必要な作業は、Aと言うポイントを選択し、他の3つの各ポイントまでの距離を計算することです。Aが1つの点からのxであり、他の2つの点からのzであることがわかる場合、それら2つの他の点を互いに照合する必要があります。それらが互いにxである場合、正方形があります。すなわち:

  • AB = z
  • AC = x
  • AD = z

AB = ADなので、BDを確認します。

  • BD = x

念のため、BCとCDの反対側を確認する必要があります。

  • BC = z
  • CD = z

AC = BDおよびAB = AD = BC = CDであるため、これは正方形です。

途中で、3つ以上の異なるエッジ距離が見つかった場合、図形を正方形にすることはできませんので、見るのをやめることができます。


実装例の実装

jsfiddleで実用的な例を作成しました(こちらを参照)。アルゴリズムの説明では、A、B、C、およびDの任意のポイントを使用します。これらの任意のポイントは、例を通り抜けるために特定の順序になっています。このアルゴリズムは、ポイントの順序が異なっていても機能しますが、これらのポイントの順序が異なる場合、このは必ずしも機能しません。


この回答を改善するための有益なコメントについては、mesuai、Bllfl、MSalters、Bart van Ingen Schenauに感謝します。


19
このプロセスを回避し、ポイント間の距離を測定し、見つかった一意の距離の数を追跡することで、ポイントの順序を気にする必要はありません。2つ(Joelのxz)を超えると、図は正方形ではありません。
Blrfl

3
もう1つの最適化は、距離ではなく、距離の2乗を比較することです。
-vaughandroid

4
@Blrfl:テストは機能しません。ABCDをAB = BC = CD = DA = 1、AC = 1(短い対角線)、AD〜1.7(長い対角線)のダイアモンドにします。
MSalters

2
@JoelBrown:対角線AC = BD = x、辺AB = BC = AD = z、最後の辺CD = y!= zの台形を作成することができます。
バートヴァンインゲンシェナウ

2
結構ですが、OPは明示的に2次元を言っていることに注意してください。
ジョエルブラウン

24

4つのポイントのうち3つを選択します。

点間の3つのベクトルの1つが90度回転した別のベクトルと等しいかどうかを確認して、それが直角二等辺三角形であるかどうかを判断します。

その場合、ベクトル加算により4番目のポイントを計算し、指定された4番目のポイントと比較します。

これは高価な平方根を必要とせず、乗算も必要としないことに注意してください。


2つの良い答えの1つ。sqrt重要でない限り使用しないでください!整数計算をFPに落とす必要はありません...言うまでもなく、FP計算の精度が悪化します。
K.ステフ

THX。いいもの。
MarshalSHI

これが正しい方法です。実際、ここでは乗算は必要ありません。
から来た

2つのベクトルが、乗算を伴うドット積なしで互いに垂直であるかどうかをどのように確認しますか?
パヴァンマンジュナート

1
直角に回転した(x、y)は(-y、x)または(y、-x)であり、それぞれ正または負の方向に回転するかどうかによって異なります。
スターブルー

17

最も簡単な解決策は次のとおりだと思います:

  • まず、4つのポイントの中心を計算します。 center = (A + B + C + D)/4

  • 次に、ベクトルを計算しA - centerます。これにしますv := (x,y)

  • ましょうv2ベクトルvを90度回転させます:v2 := (-y, x)

  • 今、他の点はあるべきcenter - vcenter + v2center - v2

このソリューションの利点は、平方根をまったく使用する必要がないことです。


2
うん。これは最もわかりやすく、おそらく最も実装しやすいでしょう。
エリックG

セグメントのベクトル等価性のようです。誰もがそれがうまくいく理由を詳しく説明したり証明したりできますか?
vCillusion

これは、(2,1)、ケース(0,0)のために特別に失敗し、(3、-1)、(1、-2) -正方形軸に整列していない
vCillusion

1
この場合に有効です。中心点は(1.5、-0.5)、最初の点は(0、0)、他の3つの点は(1.5、-0.5)+(1.5、-0.5)=(3、-1)です。(1.5、-0.5)+(0.5、1.5)=(2、1)および(1.5、-0.5)-(0.5、1.5)=(1、-2)これは正方形であることを意味します。証明は..対称性ですか?
-aragaer

1
「距離解」には平方根が必要ですが、「平方距離解」には必要なものがありません。あなたの方がもっと効率的かもしれません...
maaartinus

5

申し訳ありませんが、一部の答えは当てはまりません。

この場合、3つのエッジ(AB、AC、ADなど)を測定して、2つのサイズが同じ(ACとADなど)で、1つが大きい(ABなど)とわかります。次に、CDを測定して、ABと同じサイズかどうかを確認します。正方形の代わりに、以下の画像を使用できますが、これは間違った解決策になります。

正方形ではない...

次に、他の解決策を試みます。すべての距離を少なくとも1回測定します:AB、AC、AD、BC、BD、CD。次に、thenの4つが等しく、他の2つも同じであることがわかります。ただし、次のような写真を撮ることができます。

それも正方形ではありません...

したがって、高い賛成票を受け取ったにもかかわらず、これらの答えは正しくありません。

1つの可能な解決策:2つの等しいメジャーが同じポイントを接続しない場合。したがって、ABとCDが同じ長さである場合、他のすべての組み合わせ(AC、AD、BC、BD)も等しく、正方形になります。同じポイントで最大の長さ(ABとACが最大で、他のすべてが等しい)を持っている場合、上の写真の1つがあります。


いいえ、彼のアルゴリズムは、距離xの2つのエッジがポイントを共有しないと述べました。ただし、Cを共有するだけです。したがって、ACがxであると仮定すると、BDはBCの代わりに別のxになります。
MarshalSHI

3

4つのポイントの座標ベクトルをa、b、c、dとします。

次に、それらの差をw =(ad)、x =(ba)、y =(cb)、z =(dc)と呼びます。

その後、90度の回転でaからwを作成できる場合、wはaに直交します。数学的には、2空間の90度回転行列は((0、-1)、(1、0))です。したがって、wが90度回転したaであるかどうかの条件は、

(w_1 == -x_2およびw_2 == x_1)

これが当てはまる場合、w == -yおよびx == -zであることを確認する必要があります。または

((w_1 == -y_1 and w_2 == -y_2)および(x_1 == -z_1 and x_2 == -z_2)))

これらの3つの関係が成り立つ場合、a、b、c、dは方向付けられた正方形を作ります。


1
長方形もあなたの条件を満たすことができると思います。
-MarshalSHI

いいえ、最初の条件は直交ベクトルでは満たされていませんが、同じ長さのベクトルではありません。
マークザルツァー

1
ええ、私はちょうど最初のものが恋しいです。ただし、4つのポイントは順序付けされていません。ですから、確認するためにはもっと多くのステップが必要だと思います。
MarshalSHI

はい...巧妙なアイデアが発生しない場合、誰がループする必要があります。私は、a、b、c、dの各可能な順序からw、x、y、zを計算するための外側のループと、w、x、y、zのタプルの可能な順序ごとに1つの内側のループが必要だと思います。
マークザルツァー

2

答えに似ています starblue

4つのポイントのうち3つを選択します。

それらの中から直角の頂点を探します:3つのベクトルのいずれかの2つのドット積がゼロであるかどうかをチェックします。見つからない場合は、正方形ではありません。

この角度に隣接する頂点も直角であるかどうかを確認します。そうでない場合は、正方形ではありません。

対角線が垂直かどうかを確認します。1番目と4番目の頂点と他の2つの頂点(対角線)の間のベクトルのドット積がゼロの場合、その正方形です。


良い考えですが、4番目の頂点が他のポイントから適切な距離にあることを確認する必要があります。対角線上にあることを確認するだけです。
スターブルー

@starblue右!それ以外の場合は、カイトを形成できます。更新しました。
マックス

2

単純な加算と減算、および最小値/最大値の検索でこれを実行できると思います。用語(他の人の図と一致):

  • 最も高いy値を持つポイント=> A
  • 最高x => B
  • 最低y => C
  • 最低x => D

4つのポイントが2 x値と2 y値のみを共有している場合、レベルの正方形があります。

それ以外の場合、ポイントが次の条件を満たす場合、正方形になります。

  • Ax + Cx = Bx + Dx
  • Ay + Cy = By + Dy
  • Ay-Cy = Bx-Dx

説明:線分ACとBDは、それらの中間点で交わるべきです。したがって、(Ax + Cx)/ 2はACの中点であり、(Bx + Dx)/ 2はBDの中点です。この式の各辺に2を掛けて、最初の式を取得します。2番目の式は、Y値についても同じです。ひし形(菱形)はこれらのプロパティを満たします。したがって、辺が等しいこと、つまり幅と高さが同じであることを確認する必要があります。それが3番目の方程式です。


2

ここに画像の説明を入力してください

ここにはいくつかの良い答えがありますが、質問は最も簡単なアプローチを求めました。私はこれに簡単な考えを与えました、そして、これは私がそれをする方法です。

4つのポイントが正方形を表すかどうか(回転しても)はわかりますが、4つのポイントの平均を見つけます。

R = (A+B+C+D)/4

平均が得られたら、各ポイントと平均間の距離は、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が交差しないことを前提としています(有効な巻き順があるため)。


1

これは設定された標準によると答えではありませんが、これが役立つことを願っています:

[以下のリンクからコピーしたため、リンクを開く必要はありません] 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)として複素数のリストを受け取ります。正方形の中心と1つの角の両方がわかっている場合、中心点を中心に90、180、270度の角を回転させることで正方形を再構成できます(c)。複素平面上で、原点を中心とした90度の回転は、ポイントにiを掛けることによって行われます。元の形状と再構成された正方形のポイントが同じ場合、正方形である必要があります。

これは 、4つの点が正方形を形成するかどうかを判断する

答えが気に入ったら、少し時間を取ってその人に感謝するか、そのページで彼の答えに投票してください。


1
ここでアルゴリズムを要約できます。別のSEサイトにリンクしていますが、これは別のサイトをポイントするよりもわずかに優れていますが、このページで質問をする場所に答えが表示されるようにします。答えが何であるかを知るために、人々はもう一度クリックする必要があります。
ピーターズ

0

基本的な考え方(これは、ボットが答えを提供するためにクリックしたときに尋ねられた新しい何かを提供していたかどうかの質問に答えます):

  • 対角線が等しい菱形は正方形です。
  • 「できるだけシンプル」には以下が含まれます。
    • 分割なし、
    • 平方根なし、
    • 分岐なし
    • 検索なし、
    • 角度チェックや追跡なし、
    • ベクトルなし、
    • 変換なし、
    • 複素数なし、
    • マルチライン機能なし
    • 特別なパッケージのインポートはありません(組み込みのもののみを使用してください)。
    • (そして帝国のもつれはありません!)

Rでの私のソリューションを以下に示します。正確に 4つのポイントがあり、問題のステートメントごとに、ポイントが一意であると既に決定されていると仮定しています。

sumsq <- function(x) sum(x^2)

quadrances.xy <- function(xy) vapply(
    as.data.frame(t(diff(xy)), optional=T), sumsq, 1)

「クアドランス」の議論については、ノーマンワイルドバーガーの作品、特に彼のYouTubeビデオ(本物の魚、実数、本物の仕事など)と彼の本Divine Proportionsをご覧ください。

xyR者によって受け入れマトリックスの種類を指しplotpointsおよび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シンボルは、インデックスごとに1つの列と有するインデックス行列を意味する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
}

私は、「シンプル」には複数行の関数は含まれないと言った。この2行の関数を言い訳する必要があります。

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

4つの点に関する質問は別として、最初の4つの関数はそれ自体が有用であることに注意してください。


0

4つのポイント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)になるようにポイントを移動します。

点が正確に反時計回りの順序で正方形の角である場合、AとBが与えられると、CとDがどこにあるかを計算できます:(cx、cy)=(bx-by、bx + by)と(dx、dy)=(-by、bx)。したがって、CとDの位置から、それらの位置までの2乗距離を計算します:errC =(cx-bx + by)^ 2 +(cy-bx-by)^ 2、およびerrD =(dx + by)^ 2 +(dy-bx)^ 2。これらを追加し、(bx ^ 2 + by ^ 2)で除算して、err =(errC + errD)/(bx ^ 2 + by ^ 2)を求めます。

結果のエラーは、完全な正方形の場合は0、ほとんど正方形の場合は小さな数値になり、正方形のポイントを変換、スケーリング、または回転する場合の丸め誤差を除き、数値は変化しません。したがって、errを使用して、正方形の大きさを決定できます。

しかし、ポイントの順序はわかりません。BとDはAから同じ距離にある必要があります。これに2の平方根を掛けると、AからCまでの距離になります。これを使用して、どの点がCであるかを計算します。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を入れ替えます。

これにより、実際に正方形が存在する場合、または少なくともほぼ正方形が存在する場合、B、C、およびDが正しく配置されます。しかし、おおよその正方形さえない場合、最後のエラー計算がこれを示すことがわかります。

概要:

  1. bx、cx、dxからaxを引きます。by、cy、dyからayを引きます。
  2. distB = bx ^ 2 + by ^ 2、distD = dx ^ 2 + dy ^ 2とします。
  3. distD≥1.5 * distBの場合、CとDを入れ替えて、distDを再度計算します。
  4. それ以外の場合、distB≥1.5 * distDの場合、BとCを入れ替えて、distBを再度計算します。
  5. errD =(dx + by)^ 2 +(dy-bx)^ 2としましょう。
  6. errD≥distBの場合、BとDを交換し、distBとdistDを交換し、errDを再度計算します。
  7. errC =(cx-bx + by)^ 2 +(cy-bx-by)^ 2としましょう。
  8. err =(errC + errD)/ distBとします。
  9. errの値に応じて、正方形にするか、ほぼ正方形にするかを決定します。

ポイントの順序がわかれば、これは明らかに単純化できます。


-3

ソリューションは思考メディアに似ています。

最初の一歩:

x = (A+B+C+D)/4
f=0
if(dist(x,A) == dist(x,B) == dist(x,C) == dist(x,D) 
   f=1
else
   f=0

周期的であるため、このプロパティの後には正方形が続きます。このプロパティをたどる円。だから、今すぐチェックしてください

if(A.B==B.C==C.D==D.A==0)
  f=1
else 
  f=0

if (f==1)
  square
else 
  not square

ここでABはAとBの内積を意味します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.