円に最も近い最適なものを見つける


12

以下は、真ん中に白い点のポイントがあり、すべての赤い円がすでに存在する場合に青い円(明らかにそれを配置した場所にある)に最も近い場所を見つけたい場合の画像例です。 。その場所を見つけるにはどうすればよいですか?

私にとってパフォーマンスは、このアプリケーションにとって大きな関心事ではありません。

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


1
黒丸の意味は何ですか?その上に青い円を置くことができますか?
ユアン

2
明確にするために、他の円と重ならないように白い点から可能な限り最短距離になるように青い円を配置できる場所が必要ですか?
ロバートハーヴェイ


2
すべてのサークルは、少なくとも1か所で常に他のサークルと接触しますか?
ロバートハーヴェイ

回答:


4

これは一般的な解決策ではありません。なぜなら、青い円の位置に白い点までの最短距離が提供されない場合がいくつかあるからです。たとえば、100個の赤いボールがグループ化されており、白いドットがこの赤いボールのグループから遠く離れている場合、白いボールの中心にできる青い円の位置に影響する赤いボールはありません。 。また、すべての計算の詳細も表示されません。とにかく、ソリューションの一部(青の円)が2つの赤の円に接している
場合、1)Rを青の円の半径にする
2)赤の円のすべてのペアでループを作成する、はいこれがO(n2)であることは知っています。
3)それぞれの半径riとrjを中心とする(xi、yi)および(xj、yj)に中心を持つ円i、jの各ペアについて、円のペア間の距離の2乗を計算します

d_ij^2=(xi-xj)^2+(yi-yj)^2  

4)円のすべてのペアを置く

dij^2<R^2

リストに。

5)リストを走査し、円iとjの両方に接する半径Rの円の2つの解を見つけます。これを行うには、これらの方程式をこの画像とともに使用します 赤い円のペアに対して2つの青い円が候補

a = R+ri  
b = R+rj  
c = dij  
α = arccos((b^2+c^2-a^2)/(2bc)  

上記の情報を使用すると、(X1ij、Y1ij)および(X2ij、Y2ij)円iおよびjに接する2つの円の中心を見つけることができます。青い円の候補ごとに、他のすべての赤い円をループし、重複しないかどうかを確認します。白丸までの距離を確認しない場合、彼らはそれをdisartする場合。距離の短いものを保持する場合、円のペアのリストを走査し終えたときに解決策が得られると思います。アルゴリズムはO(n3)のようです。


サークルが1つしかない場合は動作しません
ユアン

または2つの円がターゲットポイントが両方の外側にある
ユアン

問題は、すべてのエッジケースがあることを確認できないことです。
ユアン

また。これらのケースにはユニークなソリューションがあります
ユアン

ソリューションが正しいという前提をすべて書き留めるか、少なくともすべての境界ケースを指摘する必要があります。それらのいくつかは明らかですが、いくつかはそうではありません。たとえば、すべての赤い円から白い点を分離し、最も近い円から白い点がRよりも小さい線を引くことができる場合、これは機能しません。
Vlad

2

ポイントに最も近い配置は、ポイント上にあるか、円に触れます。

したがって、最初にポイントをチェックし、次に既存の各円のエッジの周りに新しい円を転がし、ポイントからの距離を計算し、移動中にオーバーラップする場合は最小距離ポイントを追跡します。すべての円を横断したら停止します。

すなわち。緑の線上のすべての点と白い円を確認してください。ここで、緑の線は赤と青の半径を持つ円です

可能な中心点

これらのエッジケースをカバーするには、交差点だけでなく緑の線全体をチェックする必要があります。

シングルサークルケース

明らかに、パフォーマンスの観点から、トラバーサルのステップサイズが重要になります。ただし、パフォーマンスは問題ではないと述べるので、出力値の解像度に対応する値を選択します。すなわち、フロート、長い?

明確化:

私の提案は、各点で他のすべての円との重なりをテストする円の周りのすべての点をブルートフォースすることです。賢さはありません。

サンプルの写真が円の数と解像度を示している場合、標準のPCでは問題になりません

平均半径200の20の円があるので、約20 * 2π* 200ポイント* 20の交差テスト= 4800000回の繰り返し

注意:

このような反復アプローチには、ステップサイズ(この場合は出力の解像度)が結果に大きく影響する可能性があるという点で欠陥があります。

2ピクセル離れた2つの赤い円と、それらの間を絞るための半径1ピクセルの青い円があるとします。明らかに、2つのピクセルのいずれかを青い円の中心として、赤の1つと重なります。ただし、中心が2つのピクセルの間にある場合は、明らかに円のためのスペースがあります。

したがって、出力の解像度について尋ねる私のコメント。あなたは何でもいいと言った。

青い円の半径だけ半径が増加する円の各ペアの連立方程式を解くこともできます。

これにより、青い円が繰り返しよりも正確に両方の赤い円に触れるポイントが得られます。

しかしながら。これだけを行うと、間違った答えが返されるか、何も返されないという条件がいくつかあります。すなわち。

1個またはサークルなし

2つ以上の円。ただし、ターゲットポイントは遠く、外側にあります。

多くの円、ただしターゲットポイントは表面に近い


2
彼が他の円の外側に青い円の縁を転がす必要があることは、理解しやすい部分です。難しいのは、それを行うための方程式/計算を理解することです。
ロバートハーベイ

1
本当に?そのちょうど(x-x1)^ 2 +(y-y1)^ 2 =(r + r1)^ 2
ユアン

2
そして、次のポイントを試してみると、そのすべてをやり直す必要があります。OPはパフォーマンスは問題ではないと言っていましたが、宇宙の熱死の前に完了する必要があります。
ロバートハーヴェイ

2
10回の賛成票を受け取るかどうかを知る唯一の方法は、C#コードを投稿して何が起こるかを確認することです。
ロバートハーヴェイ

2
私が起こると思うのは、OPがこれを彼の宿題の答えとしてコード化し、私たちは彼から再び聞くことはありません
ユアン

1

このプランクには動作するコードが含まれており、

概念

与えられた円はC1、C2 .... Cn

円の座標CnはCnx、Cny、半径はCr

必要な円の半径はR

青い円がX、Yの位置にあり、他の円と競合しない場合、次の方程式が当てはまります

(C1x - X)^2 + (C1y - Y)^2 > (C1r + R)^2
(C2x - X)^2 + (C2y - Y)^2 > (C2r + R)^2
....
(Cnx - X)^2 + (Cny - Y)^2 > (Cnr + R)^2

最初の方程式を変更し、

C1x^2 - 2C1x*X + X^2 + C1y^2 - 2C1y*Y + Y^2 > C1r^2 + 2C1r*R + R^2
X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2

方程式は次のように書き直すことができます。

X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2
X^2 + Y^2 - 2C2x*X - 2C2y*Y > C2r^2 + 2C2r*R + R^2 - C2x^2 - C2y^2
....
X^2 + Y^2 - 2Cnx*X - 2Cny*Y > Cnr^2 + 2Cnr*R + R^2 - Cnx^2 - Cny^2

実装

白い点の座標(Xw、Yw)から開始します。

    var isValidLocation = function(x,y,r){
       var valid = true;
       for (var i = 0; i< circles.length; i++){
          var circle = circles[i];
          valid = valid && ((x*x + y*y - 2*circle.x*x - 2*circle.y*y) > (circle.radius*circle.radius + 2*circle.radius*r + r*r - circle.x*circle.x - circle.y*circle.y));
       }
       return valid;
      };

      var find = function(Xw,Yw,Rw){
        var radius = 0;
        while(true){
          for (var x=-1 * radius ;x <= radius; x++) {
            for (var y=-1 * radius;y <= radius; y++) {
               if (isValidLocation(Xw + x,Yw + y, Rw)){
                 drawCircle(Xw + x,Yw + y,Rw,"#0000FF");
                 return;
               }
            }   
          } 
          radius++;
        }
     }; 

すべての方程式を満たすことがわかった最初の座標は、青い円の位置です


誰かがこのアプローチの何が悪いのか説明してもらえますか?
低空飛ぶペリカン

読みにくい。適切な名前と抽象化を使用してください。図を追加するのはあなたを殺すでしょうか?
candied_orange

私が見る限り、このアプローチは青い円の有効な配置のみを見つけようとしますが、可能な限り最も近い場所は見つけようとしません。これは修正できますが、このアプローチでは、整数値の座標が有限数しかないという仮定(おそらく無効)も行います。
Doc Brown

それは白い点の座標から始まり、検索グリッドを広げてその周りを回ります。そのため、無限の数の座標を持つ状況には直面しません。最終的に、一致する座標を見つけます。
低空飛ぶペリカン

1
...整数座標の正しい解を得るには、半径を大きくして、探索空間を白色点を中心としたこの半径の円にする必要があります。OPは効率性を彼の関心事ではないと書いていますが、それでも、すべてのループで既にテストされたすべての座標ペアを何度もテストしないことをお勧めします。
Doc Brown

0
  • Oは、あなたが近くにいようとしているポイントであること
  • Pは、探しているポイント(青い円の中心です)
  • rは青い円の半径です
  • C0 .. Cnは、青の配置を制限するすべての円の中心です
  • 拡張円は、半径がrだけ拡張された円の1つです。

    Oが円の​​中心にない場合、いくつかの追加の作業があります。したがって、今はO == C0と仮定します

それぞれの半径とrを使用して、C0とのすべての円のすべての交差を計算します。つまり、拡張C0と拡張円を交差させます。交差点がない場合、探しているポイントはC0の任意の場所にあり、交差点がある場合は、交差点ごとに、別の拡張円内にあるかどうかを確認します(C0との交差点がある円に制限できます)。Pとして別の拡張円にない最初の交差点を取ります。他の交差点がある可能性があります。

拡張円とC0の間に別の拡張円の内側にない交点がない場合は、すべての拡張円の相互の交点を計算します。次に、これらの交差点をOまでの距離の順にチェックします。交差点のいずれかが別の拡張円内にあるかどうかを確認します。

これを想像して、青い円の可能な位置を示すすべての円の周りに線を引くとしたら、すべての拡張円を結合すると、青い円ができない領域がわかります。あなたが探しているポイントは、その組合にない最も近いポイントです。解決策であるそのユニオンにないC0に点がある場合、C0が完全に覆われている場合、Pは2つの他の拡張円の交差点にあり、それによって覆われていない領域になければなりませんこの結合(拡張円ではない)。

これはO(n ^ 2)です。これを改善する方法はいくつかありますが、グリッドを使用してペアワイズ検索の労力を減らすことができます。また、Oに近いことで円をソートすることもできます。ラジオで2つの円を減らす)カバレッジと交差点検索の検索スペースを制限するのに役立ちます


0

可能な解決策の検索

  1. 白色点がそれ自体で解決策であるかどうかを確認します。赤丸が0の場合と、赤丸が白点から遠く離れている場合の些細な場合をカバーします。
  2. 1つの赤い円。
    1. 白い点は円の中心です。可能な解決策は、中心が白い点にあり、半径が青い円の半径と赤い円の直径の合計である円上の無限の点です。それを緑の円と呼びましょう。
    2. ホワイトポイントはどこか他の場所です。白い点と赤い円の中心を結ぶ線上に考えられる解決策は1つだけです。これは、赤い円が白い点に向かって線と交差する点から離れた青い円の半径です。
  3. 2つ以上の赤い円。
    1. 赤い円を1つずつ取り、ポイント2(1つの円)に従ってそれぞれの可能な解決策を個別に探してみましょう。
    2. 赤い円のペアごとに、赤い円の両方に触れる青い円を描くことができるかどうかを確認しましょう。すなわち、それらの中心間の距離が、半径と青い円の直径の合計に等しいか、それより小さい場合。可能な場合は、2つの解決策(または、赤い円が青い円の直径からちょうど1つ離れている場合は1つ)の可能な解決策があります。

可能な解決策の中から実際の解決策を探す

これで、可能な解決策であるポイントのセットがあり、それらを反復処理し、それぞれをチェックします。

  1. ポイントが実際に解決策である場合。赤い円の中心は、この点の半径よりも近いはずです。
  2. 以前に見つかった解決策よりも白色点に近い場合。
  3. 緑の円ある場合(ポイント2.1)
    • 個々のポイントの中に緑色の円に属する解決策がない場合、緑色の円が答えです。
    • 緑色の円に個別のソリューションがあり、ソリューションが必要な場合は、そのうちの1つを選択してください。
    • 緑色の円に個別のソリューションがあり、無制限の数のソリューションがすべて必要な場合は、別の問題を解決する必要があります。緑の円から、各赤の円の個別のソリューションのペアによって定義されたすべての円弧を切り取る必要があります。

NB:アルゴリズムの実装が正確に記述されるべきだと言っているわけではありません。動的プログラミングを使用するか、機能しないことが明らかな場合は可能なソリューションをスキップして、パフォーマンスの改善を試みることができます。

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