OpenSiv3D
OpenSiv3D copied to clipboard
Triangleに外心、内心、垂心、傍心をそれぞれ求めるメンバ関数
/// <summary>
/// 外心を求めます。
/// </summary>
Vec2 Triangle::getCircumCenter() const noexcept {
double
d0 = p1.distanceFrom(p2),
d1 = p2.distanceFrom(p0),
d2 = p0.distanceFrom(p1),
t0 = d0 * (-d0 * d0 + d1 * d1 + d2 * d2) / (2 * d1 * d2),
t1 = d1 * (+d0 * d0 - d1 * d1 + d2 * d2) / (2 * d2 * d0),
t2 = d2 * (+d0 * d0 + d1 * d1 - d2 * d2) / (2 * d0 * d1);
return (t0 * p0 + t1 * p1 + t2 * p2) / (t0 + t1 + t2);
}
/// <summary>
/// 内心を求めます。
/// </summary>
Vec2 Triangle::getInnerCenter() const noexcept {
double
d0 = p1.distanceFrom(p2),
d1 = p2.distanceFrom(p0),
d2 = p0.distanceFrom(p1);
return (d0 * p0 + d1 * p1 + d2 * p2) / (d0 + d1 + d2);
}
/// <summary>
/// 垂心を求めます。
/// </summary>
Vec2 Triangle::getOrthoCenter() const noexcept {
return p0 + p1 + p2 - 2 * getCircumCenter();
}
/// <summary>
/// 傍心を求めます。
/// </summary>
/// <param name="index">どの角の二等分線上なのかを指定します。</param>
Vec2 Triangle::getExCenter(size_t index) const {
if (3 <= index) {
throw std::out_of_range("Triangle::getExcenter() index out of range");
}
const Vec2& t0 = p(index), t1 = p((index + 1) % 3), t2 = p((index + 2) % 3);
double
d0 = t1.distanceFrom(t2),
d1 = t2.distanceFrom(t0),
d2 = t0.distanceFrom(t1);
return (d1 * (t1 - t0) + d2 * (t2 - t0)) / (-d0 + d1 + d2) + t0;
}
ありがとうございます。v0.6 で Triangle 型を開発する際に参考にします。
const Vec2& t0 = p(index), t1 = p((index + 1) % 3), t2 = p((index + 2) % 3);
ではなく
const Vec2& t0 = p(index), & t1 = p((index + 1) % 3), & t2 = p((index + 2) % 3);
でした。
関連リンク: https://qiita.com/Ebishu/items/6115f2364a2e5fab5e4d
v0.6 で Triangle
に
外接円を返す getCircumscribedCircle()
内接円を返す getInscribedCircle()
メンバ関数を追加しました。垂心、傍心は活用例が少なくプライオリティが高くないので保留です。