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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python

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

Q&A

解決済

3回答

3622閲覧

何個の円が共通部分を持つのか調べたい

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

1クリップ

投稿2017/07/17 03:52

円の中心点の座標と半径の大きさがわかっていて、
最大何個の円が共通部分を持つのか調べたいです。

イメージ説明

画像の場合なら2この円が(=2)共通部分を持つと算出したいです。

import math pi = math.pi #半径10 S1 = 10*10*pi print(S1) #半径20 S2 = 20*20*pi print(S2) #半径30 S3 = 30*30*pi print(S3)

とコードを書き今円の面積を求めました。
しかし、その円の面積に対して座標をどう使えばいいのかわからなくて...。
S1の円なら[1,1]、S2の円なら[2.5,2.5]、S3の円なら[3,3]という座標があるのですがそれをどう組み合わせ最大何この円が重なっているか調べられますか?

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

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

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

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

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

guest

回答3

0

ベストアンサー

他と重なっている円がいくつあるのかという問題であっていますでしょうか?

ある円c1とある円c2について重なっているかどうかは次のように判別できます。(c1とc2はCircleクラスで、中心点xとyと半径rのプロパティを持つとします)

Python

1if (c1.x - c2.x)**2 + (c1.y - c2.y)**2 < (c1.r + c2.r)**2 2 print("重なっている") 3else: 4 print("重なっていない")

中心点同士の距離がそれぞれの半径を足した値をよりも小さければ重なっており、同じであれば接しており、大きければ離れています。

これを、全ての円同士について調べていけば、重なっている円と重なっていない円が区別できます。

Python

1class Circle: 2 def __init__(self, x, y, r): 3 self.x = x 4 self.y = y 5 self.r = r 6 def overlap(self, other): 7 return (self.x - other.x)**2 + (self.y - other.y)**2 < (self.r + other.r)**2 8 9c_list = [ 10 Circle(0.8, 1.0, 0.4), 11 Circle(2.3, 2.5, 0.6), 12 Circle(3.0, 3.0, 0.6), 13] 14 15overlap_list = [False] * len(c_list) 16 17for i in range(0, len(c_list)): 18 for j in range(i + 1, len(c_list)): 19 if c_list[i].overlap(c_list[j]): 20 overlap_list[i] = True 21 overlap_list[j] = True 22 23print(overlap_list.count(True))

もっと効率が良いアルゴリズムはあるかもしれません。

投稿2017/07/17 04:36

raccy

総合スコア21733

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

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

退会済みユーザー

退会済みユーザー

2017/07/17 05:31

質問なのですが、c_list内のCircle(0.8, 1.0, 0.4)はタプルなのでしょうか?またfor j in range(i + 1, len(c_list)):の部分はなぜi + 1としてあるのでしょうか?
raccy

2017/07/17 06:24

`Circle(0.8, 1.0, 0.4)`はCircleクラスのインスタンス生成です。タプルでもできるのですが、クラスや名前付きタプルを作った方が、何をしているのかがわかりやすくなります。 `i+1`は自分の次の円から調べていくからです。 0番目: 1番目から最後までを順番にチェック 1番目: 2番目から最後までを順番にチェック ... i番目: i+1番目から最後までを順番にチェック ... このように、次の番目から初めて行きます。なお、i番目のときに、0番目など若い番号をチェックしなくて良いのは、若い番号の時に、自分自身とのチェックが終わっているからです。こうすることで、愚直に全て回すよりも、処理数を約半分にすることができます。
退会済みユーザー

退会済みユーザー

2017/07/17 08:07

i番目: i+1番目から最後までを順番にチェック と書かれていますが、 i番目の時は i+1番目が存在しないので、i番目の時は なにもチェックしないということでしょうか?
raccy

2017/07/17 10:11

チェックは二つの円同士を調べます。 0番目: 1番目から最後までを順番にチェック というのは 0番目・1番目 -> 0番目・2番目 -> ... -> 0番目・最後 と言う意味で、 i番目: i+1番目から最後までを順番にチェック というのも i番目・i+1番目 -> i番目・i+2番目 -> ... -> i番目・最後 ということです。
guest

0

二つの円は

  • 離れている
  • 1点で外接している
  • 2点で重なる

と関係があります。(※内包のパターンもありますが、今回の場合それを場合分けする必要は無いので割愛)
それぞれの円の中心の座標を Xn, Yn、円の半径をRn としたとき、、
(X2-X1)^2+(Y2-Y1)^2 (円の中心どおしの距離の自乗 = L1)と、
(R1+R2)^2 (円の半径を合算したものの自乗 = L2)との間に、次の関係が成り立ちます。

  • 離れている L1 > L2
  • 一点で外接する L1 = L2
  • 2点で重なる L1 < L2

つまり、それぞれの円に対して、自分自身とそれ以外の円すべてに対して上の計算を行って、場合を計算してやればよいのです。

投稿2017/07/17 04:39

tacsheaven

総合スコア13703

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

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

0

面積は関係ないです。中心間が、半径の合計より小さければ、重なる箇所があります。

投稿2017/07/17 04:21

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問