前提・実現したいこと
C言語で3次元の3点(x1,y1,z1),(x2,y2,z2),(x3,y3,z3)を通る
円の中心座標を求めたいです。
発生している問題・エラーメッセージ
歯食べたところ求められそうな連立方程式の式は出てきたのですが、
それをC言語で実現する方法がわかりません。
また内積や外積等を使うとかんたんにできるとも見ましたが、
よくわかっていません。
簡単なサンプルがあればそれを動かしながら理解していけると思っているのですが、見当たらずこちらで質問させていただきました。
利用環境はgccなどC言語であれば何でもOKです。
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
中心P(x, y, z) の座標を求めたいのなら、
連立一次方程式を作って解けばいいだけの話でしょう。
C
1#include <stdio.h> // printf 2#include <math.h> // fabs 3 4void gauss(double a[3][3 + 1]) // ガウスの消去法 5{ 6 for (int i = 0; i < 3; i++) { 7 double m = 0, t; 8 int pivot = i; 9 for (int j = i; j < 3; j++) 10 if (fabs(a[j][i]) > m) 11 m = fabs(a[j][i]), pivot = j; 12 if (pivot != i) 13 for (int j = 0; j <= 3; j++) 14 t = a[i][j], a[i][j] = a[pivot][j], a[pivot][j] = t; 15 } 16 for (int k = 0; k < 3; k++) { 17 double p = a[k][k]; 18 a[k][k] = 1; 19 for (int j = k + 1; j <= 3; j++) 20 a[k][j] /= p; 21 for (int i = k + 1; i < 3; i++) { 22 double q = a[i][k]; 23 for (int j = k + 1; j <= 3; j++) 24 a[i][j] -= q * a[k][j]; 25 a[i][k] = 0; 26 } 27 } 28 for (int i = 3; --i >= 0; ) 29 for (int j = 3; --j > i; ) 30 a[i][3] -= a[i][j] * a[j][3]; 31} 32 33typedef struct Point { 34 double x, y, z; 35} Point; 36 37Point getCenter(Point A, Point B, Point C) 38{ 39 double M[3][3 + 1]; // Matrix (方程式の係数) 40 41 // P(x, y, z) は中心の座標 42 // |AP| = |BP| 43 // (x - A.x)^2 + (y - A.y)^2 + (z - A.z)^2 44 // = (x - B.x)^2 + (y - B.y)^2 + (z - B.z)^2 45 M[0][0] = 2*(B.x - A.x); 46 M[0][1] = 2*(B.y - A.y); 47 M[0][2] = 2*(B.z - A.z); 48 M[0][3] = B.x*B.x + B.y*B.y + B.z*B.z - A.x*A.x - A.y*A.y - A.z*A.z; 49 50 // |AP| = |CP| 51 // (x - A.x)^2 + (y - A.y)^2 + (z - A.z)^2 52 // = (x - C.x)^2 + (y - C.y)^2 + (z - C.z)^2 53 M[1][0] = 2*(C.x - A.x); 54 M[1][1] = 2*(C.y - A.y); 55 M[1][2] = 2*(C.z - A.z); 56 M[1][3] = C.x*C.x + C.y*C.y + C.z*C.z - A.x*A.x - A.y*A.y - A.z*A.z; 57 58 double AB[3] = { B.x - A.x, B.y - A.y, B.z - A.z }; // ベクトルAB 59 double AC[3] = { C.x - A.x, C.y - A.y, C.z - A.z }; // ベクトルAC 60 double ABxAC[3] = { // 外積ABxAC は平面ABCの法線ベクトル 61 AB[1]*AC[2] - AB[2]*AC[1], 62 AB[2]*AC[0] - AB[0]*AC[2], 63 AB[0]*AC[1] - AB[1]*AC[0], 64 }; 65 // P は 平面ABC上、法線ベクトルABxAC とベクトルAP は直交、内積が 0 66 // ABxAC[0](x - A.x) + ABxAC[1](y - A.y) + ABxAC[2](z - A.z) = 0 67 M[2][0] = ABxAC[0]; 68 M[2][1] = ABxAC[1]; 69 M[2][2] = ABxAC[2]; 70 M[2][3] = ABxAC[0]*A.x + ABxAC[1]*A.y + ABxAC[2]*A.z; 71 72 gauss(M); 73 74 Point P = { M[0][3], M[1][3], M[2][3] }; 75 return P; 76} 77 78int main(void) 79{ 80 Point A = { 2, 2, 5 }; // Point A = { x1, y1, z1 }; 81 Point B = { 1, 1, 5 }; // Point B = { x2, y2, z2 }; 82 Point C = { 3, 1, 5 }; // Point C = { x3, y3, z3 }; 83 84 Point P = getCenter(A, B, C); 85 printf("(%g, %g, %g)\n", P.x, P.y, P.z); 86}
投稿2020/05/30 06:17
編集2020/05/30 06:30総合スコア8224
0
歯食べたところ求められそうな連立方程式の式は出てきたのですが、
それをC言語で実現する方法がわかりません。
まずは連立方程式を数学的に解いて、一般解を求めましょう。そうすればあとはその解をC言語で書くだけです。
投稿2020/05/29 02:35
総合スコア146018
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/30 16:00
2020/05/30 16:20