重なり合う円の合計面積


107

最近、4つの円(中点と半径)があり、これらの円の和集合の面積を計算する必要があるという問題に遭遇しました。

画像の例:

2つの円は非常に簡単です。

三角形内にない各円の面積の割合を計算してから、三角形の面積を計算できます。

しかし、2つ以上の円があるときに使用できる賢いアルゴリズムはありますか?


15
これは本当に興味深い問題です。高校の幾何学のクラスでこれを見たのを覚えていますが、解決策は見つかりませんでした。あなたはここで答えを見つけることができない場合は、でそれを投稿してみてくださいmathoverflow.netと数学者がそれで亀裂を持ってみましょう:P
シャルルマー

25
時には、本物のプログラマーは本物の数学を必要とする
fa。

1
この質問への回答を考えてみてください-「私たちはこれらの4つの場所に住んでいる営業担当者がいて、それぞれがこれらの4つの半径のエリアにサービスを提供しています。国のどこまでカバーしますか?」営業担当のデータベースが変更された場合、これはプログラミングの質問になります。
Chris Roberts、

5
実際、これは実際のプログラマが考えたい問題の一種です。
MAK、

2
@zvolkov:回路基板は、四角と丸を下に押して、オプションでそれらをドラッグする言語で記述されています。「銅面積を計算する」。(これは、エッチング時間を計算したり、スカベンジングアートワーク、さまざまなものを追加するかどうかを知るために必要になる場合があります。)
DigitalRoss

回答:


97

外周上のすべての円の交点を見つけます(たとえば、次の図のB、D、F、H)。それらを対応する円の中心と一緒に接続して、多角形を形成します。円の結合の面積は、ポリゴンの面積+連続する交点とそれらの間の円の中心によって定義される円スライスの面積です。また、穴も考慮する必要があります。

円の重なり


17
中央に穴があるとどうなりますか?
John Gietzen、2009年

3
合計から穴の中心に接続されたポリゴンを差し引き、そのポリゴンの円スライスを合計に追加する必要があります。
Ants Aasma 2009年

3
いいですが、すべての特殊なケース(他のケースの内側の円、交差なし、穴、1点接触など)を処理するには、多くの実装の詳細が必要になると思います
fa。

1
特殊なケースはかなり簡単です。他の内側の円は、境界の交差がないために破棄されます。1点接触は、事実上、距離がゼロの2つの交点です。中心からの距離が半径の合計よりも小さい場合、2つの円が接続されているグラフ上の接続コンポーネントアルゴリズムを介して、接続されていない形状を見つけることができます。穴は、面積が最も大きいものを除いて、すべてポリゴンです。境界交差は、すべての円の内側に厳密に含まれないすべての交差です。
Ants Aasma 2009年

4
はい、しかし穴の境界線も(小さな)弧です。私はまだこれがうまく機能するために多くのコードが必要だと思います。
fa。

32

賢いアルゴリズムは確かにあると思いますが、ここでは、それを探す必要をなくすためのばかげたアルゴリズムを紹介します。

  • 円の周りに境界ボックスを置きます。
  • 境界ボックス内にランダムなポイントを生成します。
  • ランダムポイントがいずれかの円の内側にあるかどうかを確認します。
  • 単純な加算と除算によって面積を計算します(proportion_of_points_inside * area_of_bounding_box)。

確かにそれは馬鹿げているが、:

  • 必要なだけ正確な答えを得ることができ、ポイントを増やすだけです。
  • それはあなたが内側/外側の区別を計算することができるあらゆる形で機能します;
  • すべてのコアを使用できるように、美しく並列化されます。

2
これは機能しますが、このようなモンテカルロ法は、単純に均一なサンプリングに基づいているため、一般的には収束率が最高ではありません。
ShreevatsaR

2
申し訳ありませんが、私はあなたの努力に感謝し、あなたの解決策は「実用的」であると思いますが、あなたのアプローチは非常に間違っていると思います。これは可能な問題であり、ブルートフォースではなく数学によって解決する必要があります。このような問題でエネルギーとコアを浪費することは、無駄で贅沢です。
mafu 2009年

5
そうです、私は恥ずかしいですが、12,000コアのクラスターを持っているので、贅沢に余裕があります。そして、エレガントな数学的ソリューションをその多くのプロセッサーに拡張する方法を理解できません。
ハイパフォーマンスマーク

8
モンテカルロ(または任意のランダム化)アプローチに本質的に問題はありませんが、必要な精度が得られ、妥当な時間内にそうなります。
MAK、

@mafutrct、あなたは確かに正しい。ただし、数学でほとんど間違いを犯しがちです。このソリューションは、正当性をテストする簡単な方法を提供します。
Richard

18

Ants Aasmaの答えは基本的な考えを与えましたが、私はそれをもう少し具体的にしたいと思いました。以下の5つの円とそれらが分解された方法を見てください。

例

  • 青い点は円の中心です。
  • 赤い点は円の境界交差です。
  • 内側の赤い点は、他のどの円にも含まれいない円の境界交差です。

これらの3種類のドットを識別するのは簡単です。ここで、ノードが青いドットと内部が白の赤いドットであるグラフデータ構造を作成します。すべての円について、円の中央(青い点)とその各交点(白い点が内側にある赤い点)の間に境界を作成します。

これにより、サークルユニオンは、元のユニオン(つまり、パーティション)をペアで分離し、カバーする一連のポリゴン(青の影)と円形のパイ(緑の影)に分解されます。ここの各ピースは、面積を計算するのが簡単なものなので、ピースの面積を合計することによって、ユニオンの面積を計算できます。


赤と白のドットのセットはかなり簡単に計算できると思いますが、私のグラフ理論はそれほど大きくありません。アルゴリズム的に、ノード+エッジのリストから計算された領域にどのように到達しますか?
user999305 2015年

1
アルゴリズムは、ポリゴンの代わりに非重複の三角形のセットを使用することで簡略化できます。円弧(緑の領域)は、1つの円にのみ含まれる領域です。円を追加して、ポリゴンのサイズを拡大します。(最終的には、ポリゴンについてさえ話していることを忘れることができます)。ブール値のプロパティを作成し、面積も計算しやすくなります。中空の赤い点が真っ赤な点になるので、単に三角形をセットに追加し、交差する円がますます多くなることによって、円弧が「食い尽くされる」ように調整します。
Steve

16

前のソリューションとは異なるソリューションでは、四分木を使用して任意の精度で推定を生成できます。

これは、正方形が内側か外側か、または形状と交差するかがわかる場合は、どの形状の結合でも機能します。

各セルには、空、完全、部分のいずれかの状態があります。

アルゴリズムは、低解像度(たとえば、4つのセルが空としてマークされている)から始めて、四分木に円を「描く」ことにあります。各セルは次のいずれかです。

  • 少なくとも1つの円の内側で、セルを完全としてマークし、
  • すべての円の外側で、セルを空としてマークし、
  • そうでない場合は、セルを部分的としてマークします。

完了したら、面積の推定値を計算できます。完全なセルは下限を示し、空のセルは上限を示し、部分的なセルは最大面積エラーを示します。

エラーが大きすぎる場合は、適切な精度が得られるまで部分セルを調整します。

これは、多くの特殊なケースを処理する必要がある幾何学的な方法よりも実装が簡単だと思います。


3
私の推測では、これはモンテカルロの内側/外側のポイントアルゴリズムよりも速く収束します。
フランク・クルーガー、

これは実装がはるかに簡単に思えます。間違いなく、最善のブルートフォース方式が提案されています。ありがとう!
アントンハンソン、

ここでのブルートフォースは、スクイーズの定理と呼ばれます
fa。

これは、区間演算で使用する種類のアルゴリズムです。en.wikipedia.org/wiki/Interval_arithmetic
rjmunro 2009年

13

交差する2つの円の場合のアプローチが大好きです-より複雑な例に、同じアプローチのわずかなバリエーションを使用する方法を次に示します。

多数の半重複円のアルゴリズムを一般化するためのより良い洞察を与えるかもしれません。

ここでの違いは、中心をリンクすることから始めることです(したがって、円が交差する場所の間ではなく、円の中心間に頂点があります)これにより、より一般化できると思います。

(実際には、モンテカルロ法が価値があるかもしれません)

代替テキスト
(ソース:secretGeek.net


1
画像で提案されている種類のポリゴン分割を行うことは、おそらく非常に優れたアプローチになると思います。それをコード化するためにうまくいく多くの詳細があります。20個の円のチェーンをどのように処理しますか?それぞれがチェーンの最後と次だけに重なっていますか?手で簡単に理解できますが、アルゴリズムは何ですか?
PeterAllenWebb 2009年

4

(連続ではなく)離散的な答えが必要な場合は、ピクセルペイントアルゴリズムに似た処理を行うことができます。

グリッド上に円を描画し、グリッドの各セルが主に円形に含まれている(つまり、その領域の少なくとも50%がいずれかの円の内側にある)場合は、グリッドの各セルに色を付けます。グリッド全体(グリッドが円で覆われたすべての領域にわたる)に対してこれを行い、グリッド内の色付きセルの数を数えます。


3

うーん、非常に興味深い問題です。私のアプローチはおそらく次のようなものになるでしょう:

  • 任意の数の円の間の交差領域が何であるかを計算する方法を考え出します。つまり、3つの円がある場合、それらの円の間の交差が何であるかを計算できるようにする必要があります。「モンテカルロ」法はこれを近似する良い方法です(http://local.wasp.uwa.edu.au/~pbourke/geometry/circlearea/)。
  • 別の大きな円に完全に含まれている円をすべて削除します(半径と2つの円の中心間の距離の係数を見てください)必須ではないと思います。
  • 2つの円を選択し(AとBと呼びます)、次の式を使用して総面積を計算します。

(これは、円形など、どのような形状にも当てはまります)

area(A∪B) = area(A) + area(B) - area(A∩B)

ここA ∪ Bで、AはユニオンBをA ∩ B意味し、AはBと交差します(これは最初のステップから実行できます)。

  • 次に、円を追加し続け、円の領域と円の間の交差の領域の合計/減算として追加された領域の計算を続けます。たとえば、3つの円(追加の円Cを呼び出す)の場合、次の式を使用して領域を計算します。

(これは上記と同じですが、にA置き換えられていますA∪B

area((A∪B)∪C) = area(A∪B) + area(C) - area((A∪B)∩C)

area(A∪B)私たちがたどり着いたところ、そしてarea((A∪B)∩C)見つけることができる場所:

area((A∪B)nC) = area((A∩C)∪(B∩C)) = area(A∩C) + area(A∩B) - area((A∩C)∩(B∩C)) = area(A∩C) + area(A∩B) - area(A∩B∩C)

ここでも上からエリア(A∩B∩C)を見つけることができます。

トリッキーなビットは最後のステップです。サークルが追加されるほど、複雑になります。有限のユニオンとの交差の領域を計算するための拡張があると思います。あるいは、再帰的にそれを計算できるかもしれません。

モンテカルロを使用して境界の面積を概算することに関しても、任意の数の円の交点を、正確に計算できる4つの円の交点に減らすことができると信じています(これを行う方法がわからない)しかしながら)。

おそらくこれを行うにはもっと良い方法があるでしょう-余分な円が追加されるごとに複雑さが大幅に(おそらく指数関数的にですが、わかりません)増加します。


フォーマットはどうですか?また、交差と和集合にnとuを使用することについては申し訳ありませんが、おそらくもっと良い方法があります...
Justin

1
ユニコードのユニオン(∪)および交差(∩)記号を追加しました。うまくいけば彼らは動作します。
スポーク09年

3

私は重なり合った星のフィールドをシミュレートする問題に取り組んでいます。密集したフィールドの実際のディスク領域から真の星の数を推定しようとしています。私も厳密な形式分析でこれを実行できることを望んでいましたが、タスクのアルゴリズムを見つけることができませんでした。青色の背景に緑色の円盤としてスターフィールドを生成することで解決しました。その直径は確率アルゴリズムによって決定されました。単純なルーチンでそれらをペアにして、重複があるかどうかを確認できます(星のペアが黄色に変わります)。次に、色のピクセル数により、観測された領域が生成され、理論上の領域と比較されます。これにより、真のカウントの確率曲線が生成されます。ブルートフォースかもしれませんが、問題なく動作するようです。(ソース:2from.com


2

実際に実装するのが簡単で、任意に小さなエラーを生成するように調整できるアルゴリズムは次のとおりです。

  1. 同じ点を中心とする通常のポリゴンで各円を近似します
  2. 近似された円の和集合である多角形を計算します
  3. マージされたポリゴンの面積を計算します

手順2と3は、計算幾何学からの標準の見つけやすいアルゴリズムを使用して実行できます。

明らかに、各近似ポリゴンに使用する辺が多ければ多いほど、正確な回答に近づきます。正確な答えの境界を取得するために、内接および外接ポリゴンを使用して概算できます。


2

パワーダイアグラムと呼ばれるものを使用して、この問題に対する効率的な解決策があります。ただし、これは非常に重い数学であり、私がオフハンドで取り組みたいものではありません。「簡単な」ソリューションについては、ラインスイープアルゴリズムを調べてください。ここでの基本的な原則は、図をストリップに分割することです。各ストリップの面積の計算は比較的簡単です。

そのため、こすり落とさずにすべての円を含む図で、円の上部、円の下部、または2つの円の交点のいずれかの位置に水平線を描画します。これらのストリップの内側では、計算する必要があるすべての領域が同じように見えます。2つの辺が円形のセグメントに置き換えられた「台形」です。したがって、そのような形状を計算する方法を理解できる場合は、すべての個々の形状に対してそれを実行し、それらを一緒に追加するだけです。この単純なアプローチの複雑さはO(N ^ 3)です。ここで、Nは図の円の数です。いくつかの巧妙なデータ構造の使用により、このラインスイープメソッドをO(N ^ 2 * log(N))に改善できますが、本当に必要でない限り、問題を起こす価値はないでしょう。



1

解決しようとしている問題によっては、上限と下限を取得するのに十分な場合があります。上限は簡単で、すべての円の合計です。下限については、円が重ならないように単一の半径を選択できます。円が重ならないように、各円の最大の半径(実際の半径まで)を見つけやすくします。完全に重なっている円を削除することもかなり簡単です(そのような円はすべて| P_a-P_b | <= r_aを満たします)。ここで、P_aは円Aの中心、P_bは円Bの中心、r_aはAの半径です。 )そしてこれは上限と下限の両方を改善します。また、すべての円の合計ではなく、任意のペアでペア式を使用すると、より良い上限を得ることができます。「ベスト」を選ぶ良い方法があるかもしれません

上限と下限を考えると、モンテカルロアプローチをより適切に調整できるかもしれませんが、具体的なことは何も思い浮かびません。別のオプション(これもアプリケーションによって異なります)は、円をラスタライズしてピクセルをカウントすることです。基本的には、分布が固定されたモンテカルロアプローチです。


0

これは、複雑なn ^ 2log(n)のグリーンの定理を使用して解決できます。グリーンの定理に詳しくなく、詳しく知りたい場合は、カーンアカデミーのビデオメモをご覧ください。しかし、私たちの問題のために、私の説明で十分だと思います。

写真が掲載できないので写真へのリンクは申し訳ありません。(評判が足りません)

グリーンの定理の一般方程式

私が入れた場合はLMは、このような

状態

次に、RHSは単純に領域Rの面積であり、閉じた積分またはLHSを解くことによって取得できます。これがまさに私たちがやろうとしていることです。

すべてのユニオンは、交差するこのようなばらばらの円のセットに分割できます。

したがって、パスに沿って反時計回りに積分すると領域の面積が得られ、時計回りに積分すると面積の負の値が得られます。そう

AreaOfUnion =(反時計回りの赤い弧に沿った積分+時計回りの青い弧に沿った積分)

しかし、クールなトリックは、各円について、他の円の内側にない円弧を統合する場合に必要な領域を取得することです。つまり、すべての赤の円弧に沿って反時計回りの方向で統合し、時計回りの方向に沿ってすべての青の円弧に沿って統合します。仕事完了!!!

円が他の円と交差しない場合でさえ、注意が必要です。

ここに私のC ++コードへのGitHubリンクがあります


-1

(@Loadmasterによって提案された)ピクセルペインティングアプローチは、さまざまな点で数学的なソリューションより優れています。

  1. 実装ははるかに簡単です。このJSFiddleソリューションが示すように、上記の問題は100行未満のコードで解決できます(ほとんどの場合、概念的にははるかに単純であり、処理するエッジケースや例外がないためです)。
  2. それはより一般的な問題に簡単に適応します。2D描画ライブラリ(つまり、「それらすべて!」)でレンダリング可能である限り、形態に関係なく、円、楕円、スプライン、ポリゴンなど、任意の形状で機能します。一体、ビットマップ画像も。
  3. ピクセルペイントソリューションの複雑さは、数学的ソリューションの〜O [n * n]と比較して〜O [n]です。これは、シェイプの数が増えるとパフォーマンスが向上することを意味します。
  4. パフォーマンスについて言えば、ほとんどの最新の2Dライブラリ(HTML5のキャンバスなど)がレンダリング作業をグラフィックアクセラレータにオフロードするため、ハードウェアアクセラレーションは無料で提供されることがよくあります。

ピクセルペインティングの欠点の1つは、ソリューションの精度が有限であることです。しかし、状況に応じて、より大きなまたはより小さなキャンバスにレンダリングするだけで調整できます。また、2Dレンダリングコード(多くの場合、デフォルトでオンになっている)でのアンチエイリアシングは、ピクセルレベルを超える精度をもたらすことにも注意してください。したがって、たとえば、100x100の図を同じ寸法のキャンバスにレンダリングすると、1 /(100 x 100 x 255)= .000039%の精度が得られると思います...これはおそらく「十分に良い」最も厳しい問題以外はすべて。

<p>Area computation of arbitrary figures as done thru pixel-painting, in which a complex shape is drawn into an HTML5 canvas and the area determined by comparing the number of white pixels found in the resulting bitmap.  See javascript source for details.</p>

<canvas id="canvas" width="80" height="100"></canvas>

<p>Area = <span id="result"></span></p>
// Get HTML canvas element (and context) to draw into
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

// Lil' circle drawing utility
function circle(x,y,r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, Math.PI*2);
  ctx.fill();
}

// Clear canvas (to black)
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Fill shape (in white)
ctx.fillStyle = 'white';
circle(40, 50, 40);
circle(40, 10, 10);
circle(25, 15, 12);
circle(35, 90, 10);

// Get bitmap data
var id = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pixels = id.data; // Flat array of RGBA bytes

// Determine area by counting the white pixels
for (var i = 0, area = 0; i < pixels.length; i += 4) {
  area += pixels[i]; // Red channel (same as green and blue channels)
}

// Normalize by the max white value of 255
area /= 255;

// Output result
document.getElementById('result').innerHTML = area.toFixed(2);

このソリューションでは、円の面積を使用した数学的計算を行うことができません。OPの質問の要点を逃しています。非常に多くの場合、ジオメトリの形状を処理する場合、レンダリングジオメトリは戦いの半分に過ぎません
Steve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.