円と円の交点を求めるには?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mikoko

円と円の交点を求めるには?

#1

投稿記事 by mikoko » 13年前

中心座標が異なる2 つの円の中心座標と半径を入力し,その交点の座標を求めるプログラムができません。
中心座標と半径は,struct CIRCLE {int x, y, r;};と、 2 つの円(struct CIRCLE)を引数とし,交点の数(0~2)を返す関数 int Kouten(struct CIRCLE c1, struct CIRCLE c2)を使って作りたいのですが。
私はまず片方の円を原点に移動させ、次にもう片方の円を原点を軸に回転させて、両方の円の中心をx軸上にもっていき、交点を出してそれを同様に回転、移動させて交点を得ようとしたのですが・・・・。
どうかお願いします。一応作りかけを載せときます。

#include<stdio.h>
#include<math.h>

struct CIRCLE {
int x, y, r;
};

int main(void)
{
int a,b;
double x,y,y1,a2,p;
struct CIRCLE c1,c2;
printf("Input Circle 1:\nX = ");
scanf("%d",&c1.x);
printf("Y = ");
scanf("%d",&c1.y);
printf("R = ");
scanf("%d",&c1.r);
printf("Input Circle 2:\nX = ");
scanf("%d",&c2.x);
printf("Y = ");
scanf("%d",&c2.y);
printf("R = ");
scanf("%d",&c2.r);
a = c2.x -c1.x;
b = c2.y -c1.y;
printf("a = %d,b = %d\n",a,b);
p = atan2(b,a);
a = a*cos(-p) - b*sin(-p);
b = a*sin(-p) + b*cos(-p);
printf("a = %d b = %d\n",a,b);
a2 = sqrt((c2.x-c1.x)*(c2.x-c1.x) + (c2.y-c1.y)*(c2.y-c1.y));
printf("a2 = %lf\n",a2);
x = (c1.r*c1.r - c2.r*c2.r + a*a)/(2*a);
y = sqrt(c1.r*c1.r - x*x);
printf("(x,y) = (%3.1lf,%3.1lf)\n",x,y);
y1 = -1*y;
x = x*cos(p) - y*sin(p);
y = x*sin(p) + y*cos(p);
printf("x = %lf\ny = %lf\np = %lf\n",x,y,p);

if(a2 > c1.r + c2.r){
printf("Kouten:%d\n",0);
}
else if(a2 < c1.r + c2.r){
printf("Kouten:%d\n",2);
printf("(%lf,%lf),(%lf,%lf)\n",x+c1.x,y+c1.y,x+c1.x,y1+c1.y);
}else {
printf("Kouten:%d\n",1);
printf("(%lf,%lf)\n",x+c1.x,y+c1.y);
}
return 0;
}

box

Re:円と円の交点を求めるには?

#2

投稿記事 by box » 13年前

2つの円の中心間の距離と半径の和には、以下の関係があります。
1)中心間の距離>半径の和のとき、2つの円の交点は0個
2)中心間の距離=半径の和のとき、2つの円の交点(接点)は1個
3)中心間の距離<半径の和のとき、2つの円の交点は2個
これらの関係を求めるための関数が、投稿でふれられているKouten関数ですね。

1)の場合は、そこで終了です。
2)の場合は、2つの円の中心を通る直線の方程式
y1-y2
y-y1 = -----(x-x1)
       x1-x2
と円の方程式(2円のうちどちらでもいいですが、
例えば(x-x1)*(x-x1)+(y-y1)*(y-y1)=r1*r1)とを連立させれば
求まります。

3)の場合は、2個の交点を通る直線の方程式
x1-x2
y = - -----x + b
       y1-y2
のy切片bの値を求めた後、円の方程式と連立させれば求まります。

なお、2)3)いずれの場合も、直線の方程式で傾きの分母が
ゼロになる場合を意識しておく必要があります。
ゼロで割ることはできませんので。

mikoko

Re:円と円の交点を求めるには?

#3

投稿記事 by mikoko » 13年前

boxさん、わざわざ丁寧にありがとうございます。
関数の部分はわかりました。
if(a2 > c1.r + c2.r){
printf("Kouten:%d\n",0);
}
else if(a2 < c1.r + c2.r){
printf("Kouten:%d\n",2);
printf("(%lf,%lf),(%lf,%lf)\n",x+c1.x,y+c1.y,x+c1.x,y1+c1.y);
}else {
printf("Kouten:%d\n",1);
printf("(%lf,%lf)\n",x+c1.x,y+c1.y);
}
の部分を関数になおしてあげればいいみたいですね。

問題は座標回転なんですよ。ただ a = atan2(y,x) にすると不具合がおこってしまって。
p = atan2(b,a);
a = a*cos(-p) - b*sin(-p);
b = a*sin(-p) + b*cos(-p);
のところです。
(たとえば a = 0,90 や a<-90,90<a だとatan が使えなくて)
そのあたりが難しいです。
時間がある方、お願いします。 

閉鎖

“C言語何でも質問掲示板” へ戻る