- PR -

円周上の3点から円の中心を求める

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-10-11 11:38
こんにちは。
「円周上の3点から円の中心を求める」ということで、ちょっと考えてみました。
ご指摘等ありましたら突っ込んでください。
3点のそれぞれの座標を(x1,y1)(x2,y2)(x3,y3)としてp[]に中心座標を代入します。
コード:

public class circle{

public static void main (String [] args){
double [] cp = new double [2];
circle c = new circle ();
cp = c.calc (-1, 1, 1, 1, 0, 0);
System.out.println ("X= " + cp[0] + " : Y= " + cp[1]);
}

private double [] calc (double x1, double y1, double x2, double y2, double x3, double y3){
boolean pflag = false;
double [] p = new double [2];
double a1 = 0;
double b1 = 0;
double a2 = 0;
double b2 = 0;
double xc1 = (x2 - x1) * 0.5 + x1;
double yc1 = (y2 - y1) * 0.5 + y1;
double xc2 = (x3 - x2) * 0.5 + x2;
double yc2 = (y3 - y2) * 0.5 + y2;
if (y1 != y2){
a1 = (x2 - x1) / (y1 - y2);
b1 = yc1 - a1 * xc1;
}
else{
p[0] = xc1;
pflag = true;
}
if (y2 != y3){
a2 = (x3 - x2) / (y2 - y3);
b2 = yc2 - a2 * xc2;
}
else{
p[0] = xc2;
a2 = a1;
b2 = b1;
pflag = true;
}
if (!pflag){
p[0] = (b2 - b1) / (a1 - a2);
}
p[1] = a2 * p[0] + b2;
return p;
}

}


[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-10-11 14:41 ]

try〜catchを削除および処理を一部変更しました。
(ポイントが重複していたり全て一直線上に来る場合の処理が別途必要かもしれません。)

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-10-11 16:48 ]

二等分線に直交する線が垂直になった場合の処理を追加。

[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-10-11 20:07 ]
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-10-11 22:27
>Ken-Labさん
それだと2次元座標上での話になってしまいますよね。


この問題の解の公式については私も知らないのですが、
頭の体操ということで、自力で解いてみました。
---
3点A,B,Cを通る円の中心をPとする。
線分AB,ACの中点をそれぞれD,Eとし、
a = AD, b = AE
とおく。
(AからDへのベクトルを斜体字でADと表記する。)

Pは3点A,B,Cを含む平面上にあるから、
AP = xa + yb
と書け、
ADDP より a・((x-1)a + yb) = 0
AEEP より b・(xa + (y-1)b) = 0
となり、これをx,yについて解くと、
x = {(|a|^2 - ab)|b|^2} / {|a|^2|b|^2 - (ab)^2}
y = {(|b|^2 - ab)|a|^2} / {|a|^2|b|^2 - (ab)^2}
となる。
よって、原点をOとすると、
OP = OA + xa + yb
= {(2 - x - y)OA + xOB + yOC} / 2
= {(ab)|b - a|^2 OA + (a・(a - b))|b|^2 OB + (b・(b - a))|a|^2 OC} / {2(|a|^2|b|^2 - (ab)^2)}
= {(ABAC)|BC|^2 OA - (ABBC)|AC|^2 OB + (ACBC)|AB|^2 OC} / {2|AB×AC|^2}

あとは内積などの計算だけなので、
Java 3D辺りのライブラリを使えばOKでしょう。
Jun
大ベテラン
会議室デビュー日: 2003/08/25
投稿数: 141
投稿日時: 2003-10-14 09:16
どうもありがとうございます

2次元の場合は比較的式も単純だし,インターネット上にもその公式があります
たとえば

http://www.tensyo.com/urame/prog/linealgo.htm

私の解いた方法ではまず2次元の場合について解き,それを使って3次元の場合を
解き,それを使って射影空間の場合を解き,という具合にしたのですが
(このようにすると最少ではないが比較的計算量の少ない式が求まるので)
既に2次元の場合で上のページの公式と一部の符号が異なったりしますので
とても自信がありません.
いろいろな式で検算する必要があると思いますので,ベクトルで解いた式なども
参考にいろいろ計算してみます.
一般的な線型方程式を解くプログラムなどもそれ自体大変ではありますが
この際作成してみて併用してみたいと思っています

スキルアップ/キャリアアップ(JOB@IT)