/**************************************************************************** * Copyright (c) 2017-2022 by the ArborX authors * * All rights reserved. * * * * This file is part of the ArborX library. ArborX is * * distributed under a BSD 3-clause license. For the licensing terms see * * the LICENSE file in the top-level directory. * * * * SPDX-License-Identifier: BSD-3-Clause * ****************************************************************************/ #ifndef ARBORX_TETRAHEDRON_HPP #define ARBORX_TETRAHEDRON_HPP #include #include #include #include namespace ArborX::ExperimentalHyperGeometry { // Need to add a protection that the points are not in the same plane template struct Tetrahedron { ExperimentalHyperGeometry::Point<3, Coordinate> a; ExperimentalHyperGeometry::Point<3, Coordinate> b; ExperimentalHyperGeometry::Point<3, Coordinate> c; ExperimentalHyperGeometry::Point<3, Coordinate> d; }; template Tetrahedron(ExperimentalHyperGeometry::Point<3, Coordinate>, ExperimentalHyperGeometry::Point<3, Coordinate>, ExperimentalHyperGeometry::Point<3, Coordinate>, ExperimentalHyperGeometry::Point<3, Coordinate>) -> Tetrahedron; } // namespace ArborX::ExperimentalHyperGeometry template struct ArborX::GeometryTraits::dimension< ArborX::ExperimentalHyperGeometry::Tetrahedron> { static constexpr int value = 3; }; template struct ArborX::GeometryTraits::tag< ArborX::ExperimentalHyperGeometry::Tetrahedron> { using type = TetrahedronTag; }; template struct ArborX::GeometryTraits::coordinate_type< ArborX::ExperimentalHyperGeometry::Tetrahedron> { using type = Coordinate; }; namespace ArborX::Details::Dispatch { using GeometryTraits::BoxTag; using GeometryTraits::PointTag; using GeometryTraits::TetrahedronTag; // expand a box to include a tetrahedron template struct expand { KOKKOS_FUNCTION static void apply(Box &box, Tetrahedron const &tet) { Details::expand(box, tet.a); Details::expand(box, tet.b); Details::expand(box, tet.c); Details::expand(box, tet.d); } }; template struct intersects { KOKKOS_FUNCTION static constexpr bool apply(Point const &point, Tetrahedron const &tet) { static_assert(GeometryTraits::dimension_v == 3); constexpr int N = 4; Kokkos::Array v = {tet.a, tet.b, tet.c, tet.d}; // For every plane check that the vertex lies within the same halfspace as // the other tetrahedron vertex. This is a simple but possibly not very // efficient algorithm. for (int j = 0; j < N; ++j) { auto normal = (v[(j + 1) % N] - v[j]).cross(v[(j + 2) % N] - v[j]); bool same_half_space = (normal.dot(v[(j + 3) % N] - v[j]) * normal.dot(point - v[j]) >= 0); if (!same_half_space) return false; } return true; } }; } // namespace ArborX::Details::Dispatch #endif