ノート:外接円
頂点から外心を求める方法(C#言語による)。
// === 利用例 ! double[][] vertices=new double[3][]; t[0]=new double[]{-1,-1}; t[1]=new double[]{4.0,-1}; t[2]=new double[]{2.2,1.4}; double[] circumcentertoget=new double[2]; getcircumcenter(circumcentertoget, vertices); // // === 実行するメソッド! public void getcircumcenter(double[] circumcentertoget, double[][] vertices) { double[] length=new double[3], dlength=new double[3]; for (int i=0; i<3; i++) { int i1=(i+1)%3, i2=(i+2)%3; double dx=vertices[i1][0]-vertices[i2][0], dy=vertices[i1][1]-vertices[i2][1], rr=dx*dx+dy*dy, r=System.Math.Sqrt(rr); dlength[i]=rr; length[i]=r; } double sss=0, ttt=1.0; for (int i=0; i<3; i++) { int i1=(i+1)%3, i2=(i+2)%3; sss+=length[i]; ttt *= (length[i1]+length[i2]-length[i]); } double sssttt=sss*ttt; // double area=System.Math.Sqrt(sss*ttt/16); for (int i=0; i<3; i++) { int i1=(i+1)%3, i2=(i+2)%3; double cf= (dlength[i1]+dlength[i2]-dlength[i])*dlength[i]; for (int j=0; j<2; j++) { vtoget[j] += cf*vertices[i][j]; } } for (int j=0; j<2; j++) { circumcentertoget[j] /= sssttt; } }
// === --Tsukitakemochi(会話) 2013年5月21日 (火) 23:44 (UTC)
Sqrt を使うと精度が悪くなるので length は不要でしょう。
double sssttt = 0.0; for (int i = 0; i < 3; i ++) { int i1 = (i + 1) % 3, i2 = (i + 2) % 3; sssttt -= dlength[i] * dlength[i]; sssttt += dlength[i1] * dlength[i2] * 2.0; }
sssttt の計算は length がなくてもこのように書けます。--PuzzleBachelor(会話) 2013年6月1日 (土) 10:02 (UTC)
しばらくぶりに見たら、しっかりチェック頂いており、光栄です。精度の良し悪しは私には不明ですが、手順が簡素化しますね。これを頂くと次のようになると思います(私のもとのプログラムにバグもありましたので)。
// === 実行するメソッド! public void getcircumcenter(double[] circumcentertoget, double[][] vertices) { double[] dlength=new double[3]; for (int i=0; i<3; i++) { int i1=(i+1)%3, i2=(i+2)%3; double dx=vertices[i1][0]-vertices[i2][0], dy=vertices[i1][1]-vertices[i2][1], rr=dx*dx+dy*dy; dlength[i]=rr; } double sssttt = 0.0; circumcentertoget[0]=circumcentertoget[1]=0; for (int i=0; i<3; i++) { int i1=(i+1)%3, i2=(i+2)%3; sssttt += dlength[i] * (dlength[i1] * 2.0-dlength[i]); double cf= (dlength[i1]+dlength[i2]-dlength[i])*dlength[i]; for (int j=0; j<2; j++) { circumcentertoget[j] += cf*vertices[i][j]; } } // double area=System.Math.Sqrt(sssttt/16); for (int j=0; j<2; j++) { circumcentertoget[j] /= sssttt; } }
なお、私のはもともと、幾何学的な見識を素朴に整理するところから出てきました。 ご指摘頂いた発想の根拠は私には不明ですが、式が正しいことは展開してみれば自明と言えます。--Tsukitakemochi(会話) 2013年11月23日 (土) 14:55 (UTC)
三角形外心位置ベクトルの証明
[編集]「ページ」に置かれている式
は、次のように証明できる。
ステップ1
[編集]ΔABC の外心を U とし、これと、各頂点とを線で結ぶと、小三角形が3つ現れる。 ここに結んだ各線分の長さは U の性質上等しいはずであり、これを r とする。個々の小三角形は、二等辺三角形だが、これは二等角三角形でもあることを意味する。ΔUBC、ΔUCAのそれぞれにつき、内角の和は180°だから、
- ∠CUB=180°- (∠UBC + ∠BCU) = 180°- 2∠BCU
- ∠AUC = 180°- (∠UCA + ∠CAU) = 180°- 2∠UCA
一方、U の全周を分担する角に目をつけると、
- ∠BUA = 360°- (∠AUC + ∠CUB)
- = 2 (∠BCU +∠UCA)
- = 2 ∠BCA
ステップ2
[編集]r および a, b, c (頂点 A,B,C の各対辺) を用いると、各二等辺三角形の高さ(元の三角形の辺とUとの距離)はそれぞれ r cos∠CAB、 r cos∠ABC、 r cos∠BCA。面積 SA, SB, SC は, それぞれ (a r cos∠CAB)/2、 (b r cos∠ABC)/2、 (c r cos∠BCA)/2。 これらから、もともとの三角形の面積Sは、
- S = r(a cos∠CAB + b cos∠ABC + c cos∠BCA)/2.
ステップ3
[編集]ΔABCと、ΔABUを、共通辺cを底辺と見て比較すると、三角形の面積の性質上、それはお互いの高さに比例するはずである。 Uを通り、辺ABに並行な線を引くと、これによってΔABCの斜辺 CA (長さは b) は両三角形の高さに比例する割合で分割され、図3に従えば、
- m/b = SC/S = c cos∠BCA/(a cos∠CAB + b cos∠ABC + c cos∠BCA).
次に、Uを通り、辺CAに平行な線を引き、ΔABCと、ΔABUを、共通辺 b を底辺と見て比較、ΔABCの斜辺 AB (長さは c) の分割を見ると、図に従えば、
- n/c = SB/S = b cos∠ABC/(a cos∠CAB + b cos∠ABC + c cos∠BCA).
左下に現れた 平行四辺形 を使うと、 U の位置ベクトルは、
- U = A + (C-A)m/b + (B-A)n/c
- = A + ((C-A)c cos∠BCA + (B-A)b cos∠ABC) /(a cos∠CAB + b cos∠ABC + c cos∠BCA)
- = (A a cos∠CAB + B b cos∠ABC + C c cos∠BCA)/(a cos∠CAB + b cos∠ABC + c cos∠BCA).
ここで、
等の余弦定理をあてはめると、
--Tsukitakemochi(会話) 2019年2月28日 (木) 15:33 (UTC)
検証
[編集]- ステップ1
- UがABCを通る円の中心なので、円周角の定理からただちに ∠BUA = 2∠BCA が言える。
- ステップ2
- 2辺夾角を用いた三角形の面積の式を用いれば SA=r2sin(BUC)/2。ステップ1の結果と正弦定理を利用して変形すれば SA=ar cos(A)/2。SB,SC も同様。
- ステップ3
- ステップ2と余弦定理より SA:SB:SC = a cos(A) : b cos(B) : c cos(C) = a2(b2+c2-a2) : b2(c2+a2-b2) : c2(a2+b2-c2)。
- AU と BC の交点を X とすると、BX : CX = SC : SB , AU : UX = SB + SC : SA。
- これを整理すると
- がいえる。
最後の式は三角形の中心を重心座標で扱うときには必須とも言える式です。--PuzzleBachelor(会話) 2020年11月8日 (日) 13:38 (UTC)