/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2016-2018 Danny Robson */ #pragma once #include "../point.hpp" #include "sample/fwd.hpp" #include #include namespace cruft::geom { /////////////////////////////////////////////////////////////////////////// template struct tri { tri () = default; tri (point _a, point _b, point _c) : a (_a) , b (_b) , c (_c) { ; } cruft::point a, b, c; }; template tri (point, point, point) -> tri; template using tri2 = tri<2, T>; template using tri3 = tri<3, T>; using tri2f = tri<2,float>; using tri3f = tri<3,float>; namespace sample { template class surface> { public: using shape_type = tri; explicit surface (tri _target): base (_target.a), v0 (_target.b - _target.a), v1 (_target.c - _target.a) { ; } template cruft::point operator() (GeneratorT &&gen) const noexcept { std::uniform_real_distribution dist (0, 1); return base + dist (gen) * v0 + dist (gen) * v1; } private: cruft::point base; cruft::vector v0; cruft::vector v1; }; }; /////////////////////////////////////////////////////////////////////////// // n-dimensional triangle area template ValueT area (tri obj) { // heron's formula const auto ab = cruft::distance (obj.a, obj.b); const auto bc = cruft::distance (obj.b, obj.c); const auto ca = cruft::distance (obj.c, obj.a); const auto s = (ab + bc + ca) / 2; return std::sqrt (s * (s - ab) * (s - bc) * (s - ca)); } //------------------------------------------------------------------------- // 2-dimension triangle area template T area (tri<2,T> obj) { // | x1 y1 1 | // area = 0.5 det | x2 y2 1 | // | x3 y3 1 | return std::abs ( -obj.b.x * obj.a.y +obj.c.x * obj.a.y +obj.a.x * obj.b.y -obj.c.x * obj.b.y -obj.a.x * obj.c.y +obj.b.x * obj.c.y ) / 2; } //------------------------------------------------------------------------- // 3-dimension triangle area template T area (tri<3,T> obj) { const auto ab = obj.a - obj.b; const auto ac = obj.a - obj.c; return norm (cross (ab, ac)) / 2; } //------------------------------------------------------------------------- // convenience forwarder template T area (point a, point b, point c) { return area (tri (a, b, c)); } //------------------------------------------------------------------------- template bool inclusive (tri2 const &obj, point2 const &p); };