File indexing completed on 2025-01-18 10:05:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <iostream>
0012 #include <vector>
0013
0014 #include "corecel/cont/Array.hh"
0015 #include "corecel/cont/Range.hh"
0016 #include "corecel/cont/Span.hh"
0017 #include "corecel/math/ArrayOperators.hh"
0018 #include "corecel/math/ArrayUtils.hh"
0019 #include "orange/OrangeTypes.hh"
0020
0021 namespace celeritas
0022 {
0023 namespace orangeinp
0024 {
0025 namespace detail
0026 {
0027
0028
0029
0030
0031 enum class Orientation
0032 {
0033 clockwise = -1,
0034 collinear = 0,
0035 counterclockwise = 1,
0036 };
0037
0038
0039
0040
0041
0042
0043
0044 inline Orientation
0045 calc_orientation(Real2 const& a, Real2 const& b, Real2 const& c)
0046 {
0047 auto crossp = (b[0] - a[0]) * (c[1] - b[1]) - (b[1] - a[1]) * (c[0] - b[0]);
0048 return crossp < 0 ? Orientation::clockwise
0049 : crossp > 0 ? Orientation::counterclockwise
0050 : Orientation::collinear;
0051 }
0052
0053
0054
0055
0056
0057
0058
0059 inline bool has_orientation(Span<Real2 const> corners, Orientation o)
0060 {
0061 CELER_EXPECT(corners.size() > 2);
0062 for (auto i : range(corners.size()))
0063 {
0064 auto j = (i + 1) % corners.size();
0065 auto k = (i + 2) % corners.size();
0066 if (calc_orientation(corners[i], corners[j], corners[k]) != o)
0067 return false;
0068 }
0069 return true;
0070 }
0071
0072
0073
0074
0075
0076 inline bool
0077 is_same_orientation(Orientation a, Orientation b, bool degen_ok = false)
0078 {
0079 if (a == Orientation::collinear || b == Orientation::collinear)
0080 {
0081 return degen_ok;
0082 }
0083 return (a == b);
0084 }
0085
0086
0087
0088
0089
0090
0091
0092
0093 inline bool is_convex(Span<Real2 const> corners, bool degen_ok = false)
0094 {
0095 CELER_EXPECT(corners.size() > 2);
0096 auto ref = Orientation::collinear;
0097 for (auto i : range<size_type>(corners.size()))
0098 {
0099 auto j = (i + 1) % corners.size();
0100 auto k = (i + 2) % corners.size();
0101 auto cur = calc_orientation(corners[i], corners[j], corners[k]);
0102 if (ref == Orientation::collinear)
0103 {
0104
0105 ref = cur;
0106 }
0107 if (!is_same_orientation(cur, ref, degen_ok))
0108 {
0109
0110
0111 return false;
0112 }
0113 }
0114 return true;
0115 }
0116
0117
0118 }
0119 }
0120 }