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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

2484閲覧

3次元 円の中心座標の求め方

santyago

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/05/29 02:28

前提・実現したいこと

C言語で3次元の3点(x1,y1,z1),(x2,y2,z2),(x3,y3,z3)を通る
円の中心座標を求めたいです。

発生している問題・エラーメッセージ

歯食べたところ求められそうな連立方程式の式は出てきたのですが、
それをC言語で実現する方法がわかりません。
また内積や外積等を使うとかんたんにできるとも見ましたが、
よくわかっていません。

簡単なサンプルがあればそれを動かしながら理解していけると思っているのですが、見当たらずこちらで質問させていただきました。

利用環境はgccなどC言語であれば何でもOKです。

よろしくお願いします。

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

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

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

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

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

guest

回答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
kazuma-s

総合スコア8224

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

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

santyago

2020/05/30 16:00

サンプルありがとうございました。 連立方程式をC言語で解く方法がわかってませんでした。 こちらを参考に理解していきたいと思います。
kazuma-s

2020/05/30 16:20

> 歯食べたところ求められそうな連立方程式の式は出てきたのですが、 その調べた連立方程式というのを、質問に追記してもらえませんか? 質問は編集できます。
guest

0

(3点が一直線に並んでいなければ,という条件が前提としてあるでしょうが)
3点を頂点とした三角形の外心(外接円の中心)を求めればよいのではないでしょうか.

外接円の求め方はググれば見つかるかと思います.

投稿2020/05/29 04:13

fana

総合スコア11996

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

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

fana

2020/05/31 06:40

質問文の雰囲気から,ガチで連立方程式を扱うよりもマシな方法を求めているのかと思ったのだけど,ちがったみたい.
guest

0

歯食べたところ求められそうな連立方程式の式は出てきたのですが、

それをC言語で実現する方法がわかりません。

まずは連立方程式を数学的に解いて、一般解を求めましょう。そうすればあとはその解をC言語で書くだけです。

投稿2020/05/29 02:35

maisumakun

総合スコア146018

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問