Commit 23d12b23 authored by Philip Trettner's avatar Philip Trettner

added circumcenter and incenter functions

parent e42c96cc
......@@ -30,6 +30,12 @@
namespace tg
{
template <int D, class ScalarT>
[[nodiscard]] constexpr pos<D, ScalarT> project(pos<D, ScalarT> const&, pos<D, ScalarT> const& target_p)
{
return target_p;
}
// ============== project to plane ==============
template <int D, class ScalarT>
......
......@@ -8,26 +8,43 @@
namespace tg
{
template <class ScalarT>
[[nodiscard]] sphere<2, ScalarT> circumcircle_of(triangle<2, ScalarT> const& t)
template <int D, class ScalarT>
[[nodiscard]] pos<D, ScalarT> circumcenter_of(triangle<D, ScalarT> const& t)
{
auto const& a = t.pos0;
auto const& b = t.pos1;
auto const& c = t.pos2;
auto const a2 = distance_sqr(t.pos0, t.pos1);
auto const b2 = distance_sqr(t.pos1, t.pos2);
auto const c2 = distance_sqr(t.pos2, t.pos0);
auto const d = ScalarT(2) * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
auto const a_len_sqr = distance_sqr_to_origin(a);
auto const b_len_sqr = distance_sqr_to_origin(b);
auto const c_len_sqr = distance_sqr_to_origin(c);
auto const x = (a_len_sqr * (b.y - c.y) + b_len_sqr * (c.y - a.y) + c_len_sqr * (a.y - b.y)) / d;
auto const y = (a_len_sqr * (c.x - b.x) + b_len_sqr * (a.x - c.x) + c_len_sqr * (b.x - a.x)) / d;
auto const center = pos<2, ScalarT>(x, y);
auto const r = distance(center, a);
auto A = a2 * (b2 + c2 - a2);
auto B = b2 * (c2 + a2 - b2);
auto C = c2 * (a2 + b2 - c2);
auto const f = ScalarT(1) / (A + B + C);
A *= f;
B *= f;
C *= f;
return t.pos0 * B + t.pos1 * C + t.pos2 * A;
}
return {center, r};
template <int D, class ScalarT>
[[nodiscard]] ScalarT circumradius_of(triangle<D, ScalarT> const& t)
{
auto const a2 = distance_sqr(t.pos0, t.pos1);
auto const b2 = distance_sqr(t.pos1, t.pos2);
auto const c2 = distance_sqr(t.pos2, t.pos0);
return sqrt(a2 * b2 * c2) / (4 * area_of(t));
}
template <int D, class ScalarT>
[[nodiscard]] sphere<2, ScalarT, D> circumcircle_of(triangle<D, ScalarT> const& t)
{
auto const center = circumcenter_of(t);
auto const r = distance(center, t.pos0);
if constexpr (D == 2)
return {center, r};
else
return {center, r, normal_of(t)};
}
template <class ObjectT>
[[deprecated("use circumcircle_of")]] [[nodiscard]] constexpr auto circumcircle(ObjectT const& o) -> decltype(circumcircle_of(o))
......@@ -35,6 +52,41 @@ template <class ObjectT>
return circumcircle_of(o);
}
template <int D, class ScalarT>
[[nodiscard]] pos<D, ScalarT> incenter_of(triangle<D, ScalarT> const& t)
{
auto a = distance(t.pos0, t.pos1);
auto b = distance(t.pos1, t.pos2);
auto c = distance(t.pos2, t.pos0);
auto const f = ScalarT(1) / (a + b + c);
a *= f;
b *= f;
c *= f;
return t.pos0 * b + t.pos1 * c + t.pos2 * a;
}
template <int D, class ScalarT>
[[nodiscard]] ScalarT inradius_of(triangle<D, ScalarT> const& t)
{
auto const a = distance(t.pos0, t.pos1);
auto const b = distance(t.pos1, t.pos2);
auto const c = distance(t.pos2, t.pos0);
auto const s = (a + b + c) / 2;
return sqrt(max(ScalarT(0), (s - a) * (s - b) * (s - c) / s));
}
template <int D, class ScalarT>
[[nodiscard]] sphere<2, ScalarT, D> incircle_of(triangle<D, ScalarT> const& t)
{
auto const center = incenter_of(t);
auto const r = inradius_of(t);
if constexpr (D == 2)
return {center, r};
else
return {center, r, normal_of(t)};
}
/// given a 2D triangle, returns a 3x3 matrix M such that
/// M * (a, b, c) = (p, 1)
/// where a,b,c are barycentric coordinates for p
......@@ -88,4 +140,20 @@ template <int D, class ScalarT>
{
return from_barycoord_matrix_of(to) * to_barycoord_matrix_of(from);
}
/// returns the minimum altitude/height of a triangle
template <int D, class ScalarT>
[[nodiscard]] ScalarT min_height_of(triangle<D, ScalarT> const& t)
{
auto const area = area_of(t);
return area / tg::max(distance(t.pos0, t.pos1), distance(t.pos1, t.pos2), distance(t.pos2, t.pos0));
}
/// returns the maximum altitude/height of a triangle
template <int D, class ScalarT>
[[nodiscard]] ScalarT max_height_of(triangle<D, ScalarT> const& t)
{
auto const area = area_of(t);
return area / tg::min(distance(t.pos0, t.pos1), distance(t.pos1, t.pos2), distance(t.pos2, t.pos0));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment