これは実際には単純な線形代数の問題なので、計算を記号的に行うことができます。3 つの点の x 値と y 値を代入すると、3 つの未知数で 3 つの線形方程式が得られます。
A x1^2 + B x1 + C = y1
A x2^2 + B x2 + C = y2
A x3^2 + B x3 + C = y3
これを解決する簡単な方法は、行列を逆にすることです
x1^2 x1 1
x2^2 x2 1
x3^2 x3 1
ベクトルを掛けます
y1
y2
y3
この結果は...わかりました、それほど単純ではありません;-)私はMathematicaでそれを行いました.ここに疑似コードの式があります:
denom = (x1 - x2)(x1 - x3)(x2 - x3)
A = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom
B = (x3^2 * (y1 - y2) + x2^2 * (y3 - y1) + x1^2 * (y2 - y3)) / denom
C = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom
あるいは、行列の計算を数値的に行いたい場合は、通常、線形代数システム ( ATLASなど、C#/C++ バインディングがあるかどうかはわかりません) を使用します。
いずれにせよ、これらの式で計算されたA
、B
、およびの値をC
取得したら、それらを質問で指定された式に差し込むだけ-B / 2A
でC - B^2/4A
、頂点の座標を計算できます。1
元の 3 点の座標がdenom
非常に大きな数または非常に小さな数になる場合、直接計算を行うと、重大な数値エラーが発生する可能性があることに注意してください。その場合、分母で割ることを避けるために、少し変更する方が良いかもしれません。
denom = (x1 - x2)(x1 - x3)(x2 - x3)
a = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2))
b = (x3^2 * (y1 - y2) + x2^2 * (y3 - y1) + x1^2 * (y2 - y3))
c = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3)
そして、頂点の座標は-b / 2a
と(c - b^2 / 4a) / denom
です。このような「トリック」の恩恵を受ける可能性のある状況は他にもさまざまあります。たとえば、A
が非常に大きいか非常に小さい場合、またはC
がほぼ等しいB^2 / 4A
ために差が非常に小さい場合などです。ケースバイケースのフォローアップの質問のために残しておいたほうがよいでしょう。
これらすべてを選択した言語のコードに変換することは、読者の課題として残されています。(たとえばAZDean が C# で示したように、標準の中置演算子構文を使用する言語では、かなり簡単なはずです。)
1回答の最初のバージョンでは、これは明らかだと思いましたが、明示的に言及することを好む人がたくさんいるようです。