質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3116閲覧

【Python】ランダム配置の円に対する接点の抽出

Kashi_wamochi

総合スコア14

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/09/13 12:57

編集2020/09/14 03:58

前提・実現したいこと

現在、Pythonを用いた円のRandom Packingに取り組んでいます。
現時点では、指定個数かつ半径が異なる円を重ならないように配置するプログラムまでは書くことはできました。
下記にコードを示します。

Python

1import cvxpy as cvx 2import numpy as np 3import matplotlib.pyplot as plt 4import dccp 5 6n = 40 7r = np.linspace(1,5,n) 8 9c = cvx.Variable((n,2)) 10constr = [] 11for i in range(n-1): 12 for j in range(i+1,n): 13 constr.append(cvx.norm(c[i,:]-c[j,:])>=r[i]+r[j]) 14prob = cvx.Problem(cvx.Minimize(cvx.max(cvx.norm(c, axis=1)+r)), constr) 15# prob = cvx.Problem(cvx.Minimize(cvx.max(cvx.max(cvx.abs(c),axis=1)+r)), constr) 16prob.solve(method = 'dccp', ccp_times = 1) 17 18l = cvx.max(cvx.max(cvx.abs(c),axis=1)+r).value*2 19pi = np.pi 20ratio = pi*cvx.sum(cvx.square(r)).value/cvx.square(l).value 21print("ratio =", ratio) 22print(prob.status)

次の画像はmatplotlibで結果を描画したものです。

イメージ説明

この図から以下の情報を抽出したいと考えています。

  • 接点の位置
  • 2円の接点と中心を通る線の方向ベクトル

なお上記のコードで求めた円は厳密には接していないため、ここでの「接点」は(2円の中心間距離)-(2円の半径の和)<(ある閾値)を満たすものとしたいです。

発生している問題

現在考えた手法としては以下のようなものがあります

  1. 各円とそれ以外の円の中心を結ぶ直線の方程式を抽出
  2. 1で抽出した直線の方程式に対して、2円を除くすべての円について交差判定を実施
  3. 交差しなかった直線のみから方向ベクトルと接点位置を計算

しかしながらこの方法の問題点は計算量がO(n^3)と大きくなってしまうことです。

質問

以上を踏まえまして、下記が質問となります。

  1. 上記の計算量を減らすアルゴリズムなどは存在しますでしょうか?
  2. 1.につきまして参考文献などがありましたら、教えていただけますでしょうか?

追記

今回は円の直径が異なるため、閾値よりも小さい半径を持つ円が存在した場合、(2円の中心間距離)-(2円の半径の和)<(ある閾値)のみで判定を行うと、図のような間違った結果が出てきてしまいます。

イメージ説明

これを避けるために交差判定が必要と考え、上記の手法に加えております。。

何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

2個の円が

(2円の中心間距離)-(2円の半径の和)<(ある閾値)

を満たすなら「接点」を計算する……という話ではダメなのでしょうか?
(総当りでも O(n^2) に思える)

投稿2020/09/13 15:26

fana

総合スコア11708

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kashi_wamochi

2020/09/14 03:25

ご回答ありがとうございます。 ご指摘の方法で試してみたのですが、半径が等しい円の場合はその方法で問題ありませんでした。 ただ今回は半径にばらつきがあり、図のような配置の場合、円3も間違って接点として検出されてしまいます...(図は質問内に追記させていただきました) そのため交差判定が必要なのではと思い、上記のような考えに至りました。
fana

2020/09/14 03:50

> 質問内に追記 I can't find it.
Kashi_wamochi

2020/09/14 03:58

すみません。ただいま追記させていただきました。
Kashi_wamochi

2020/09/14 04:02

追記した図では円1と円0がかなり離れているように見えるかもしれませんが、これは図化のために若干誇張して書かせていただきました。 実際の解析では円1がより大きく、円2や円3がより小さいものになる予定です。
fana

2020/09/14 04:18

正直いまいち話が謎なのですが, この世界における「"接している"とは何なのか?」というところが不明瞭であるということに思えます. 円のサイズにものすごい開きがある,という話なのであれば, 閾値を定数ではなく,円のサイズに応じて(判定対象たる2つの円の半径に基づいて)可変させるような話で多少は逃げられるようにも思えますが… 果たして?
fana

2020/09/14 04:28 編集

あと,「交差判定」の話とのつながりもわからないです. (私が,そこの話の意味を理解できていないのだと思いますが…) 例えばその図で,円0と3との関係は ・円2が存在すれば,接触していない ・円2が存在しないならば,接触している として扱うのでしょうか?(0と3の距離は同じなのに,扱いが変わる?)
fana

2020/09/14 04:34 編集

そういう話(複数の細かい円の並びが,「閾値」が作る帯の幅の中に入り込んでしまうことに問題がある)である場合, 最初にボロノイ図みたいなのを作って,判定対象自体を絞るような話にすれば良いのかもしれません. (あるいは,許されるならば,円の配置自体をボロノイ図から出発するとか?)
Kashi_wamochi

2020/09/14 05:06

詳しい回答をありがとうございます。 >この世界における「"接している"とは何なのか?」というところが不明瞭であるということに思えます. こちらの書き方が不適切でした。より正確な書き方をすれば、今回行いたいのは、「接するあるいは隣り合う2円の中心点を結んだ位置ベクトルを求めたい」ということです。ここでの「接するあるいは隣り合う」というのは、下記の条件を満たすものになります。 1. (2円の中心間距離)-(2円の半径の和)<(ある閾値) 2. 中心同士を結んだ線が他の円と交差しない >あと,「交差判定」の話とのつながりもわからないです. 上の条件のうち、2が「交差判定」と呼ばれるものになります。(勝手に名前を付けておいて、説明をつけておりませんでした。申し訳ありません。) >最初にボロノイ図みたいなのを作って,判定対象自体を絞るような話にすれば良いのかもしれません. ありがとうございます。恥ずかしながらボロノイ図について発想が回りませんでした。 試してみたいと思います。
KAZENOMACHI

2021/03/29 01:55

すみませんが、作画をmatplotlibで行ったとありますが、どのようなコードになるのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問