src/geo2d/ds/cvh/lib.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../dot/lib.hpp" | ||
| 4 | #include "../../ds/po/lib.hpp" | ||
| 5 | #include "../../ins/ll/lib.hpp" | ||
| 6 | |||
| 7 | namespace tifa_libs { | ||
| 8 | |||
| 9 | template <class FP> | ||
| 10 | struct cvh : public polygon<FP> { | ||
| 11 | ✗ | CEXP cvh() = default; | |
| 12 | 767304 | CEXPE cvh(u32 sz) NE : polygon<FP>(sz) {} | |
| 13 | 5009 | CEXP cvh(spn<point<FP>> vs_, bool inited = false, bool strict = true) NE : polygon<FP>(vs_) { | |
| 14 |
5/8tifa_libs::cvh<double>::cvh(std::span<tifa_libs::point<double> const, 18446744073709551615ul>, bool, bool):
✓ Branch 0 taken 338 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 331 times.
✓ Branch 3 taken 7 times.
tifa_libs::cvh<long double>::cvh(std::span<tifa_libs::point<long double> const, 18446744073709551615ul>, bool, bool):
✗ Branch 0 not taken.
✓ Branch 1 taken 4656 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
5009 | if (!inited) strict ? init<true>() : init<false>(); |
| 15 | 5009 | } | |
| 16 | |||
| 17 | 767309 | friend auto& operator>>(istream_c auto& is, cvh& ch) NE { | |
| 18 |
6/6auto& tifa_libs::operator>><std::istream>(std::istream&, tifa_libs::cvh<double>&):
✓ Branch 6 taken 750812 times.
✓ Branch 7 taken 294 times.
auto& tifa_libs::operator>><std::istream>(std::istream&, tifa_libs::cvh<long double>&):
✓ Branch 6 taken 22668672 times.
✓ Branch 7 taken 367126 times.
auto& tifa_libs::operator>><std::istream>(std::istream&, tifa_libs::cvh<long>&):
✓ Branch 6 taken 11497456 times.
✓ Branch 7 taken 399889 times.
|
35684249 | for (auto& i : ch.vs) is >> i; |
| 19 | 767309 | return is; | |
| 20 | } | ||
| 21 | friend auto& operator<<(ostream_c auto& os, cvh<FP> CR ch) NE { | ||
| 22 | retif_((ch.vs.empty()) [[unlikely]], os); | ||
| 23 | for (auto it = begin(ch.vs); it != end(ch.vs) - 1; ++it) os << *it << ' '; | ||
| 24 | return os << ch.vs.back(); | ||
| 25 | } | ||
| 26 | |||
| 27 | template <bool strict = true> | ||
| 28 | 767870 | CEXP cvh& init() NE { | |
| 29 | 767870 | this->reunique(); | |
| 30 | 767870 | cu32 n = this->size(); | |
| 31 |
7/10tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<false>():
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<true>():
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 754 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<false>():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<true>():
✓ Branch 0 taken 20207 times.
✓ Branch 1 taken 346939 times.
tifa_libs::cvh<long>& tifa_libs::cvh<long>::init<true>():
✓ Branch 0 taken 58253 times.
✓ Branch 1 taken 341636 times.
|
767870 | retif_((n <= 2) [[unlikely]], *this); |
| 32 | 689360 | vec<point<FP>> cvh(n * 2); | |
| 33 | 689360 | u32 m = 0; | |
| 34 |
8/10tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<false>():
✓ Branch 2 taken 487508 times.
✓ Branch 3 taken 31 times.
tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<true>():
✓ Branch 2 taken 500694 times.
✓ Branch 3 taken 754 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<false>():
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<true>():
✓ Branch 2 taken 21021027 times.
✓ Branch 3 taken 346939 times.
tifa_libs::cvh<long>& tifa_libs::cvh<long>::init<true>():
✓ Branch 2 taken 9103446 times.
✓ Branch 3 taken 341636 times.
|
31802035 | for (u32 i = 0; i < n; cvh[m++] = (*this)[i++]) |
| 35 | if CEXP (strict) | ||
| 36 |
18/18tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<true>():
✓ Branch 0 taken 914915 times.
✓ Branch 1 taken 63385 times.
✓ Branch 6 taken 477606 times.
✓ Branch 7 taken 437309 times.
✓ Branch 8 taken 477606 times.
✓ Branch 9 taken 500694 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<true>():
✓ Branch 0 taken 37493898 times.
✓ Branch 1 taken 2254030 times.
✓ Branch 6 taken 18726901 times.
✓ Branch 7 taken 18766997 times.
✓ Branch 8 taken 18726901 times.
✓ Branch 9 taken 21021027 times.
tifa_libs::cvh<long>& tifa_libs::cvh<long>::init<true>():
✓ Branch 0 taken 13948393 times.
✓ Branch 1 taken 2232035 times.
✓ Branch 6 taken 7076982 times.
✓ Branch 7 taken 6871411 times.
✓ Branch 8 taken 7076982 times.
✓ Branch 9 taken 9103446 times.
|
56906656 | while (m > 1 && sgn_cross(cvh[m - 2], cvh[m - 1], (*this)[i]) <= 0) --m; |
| 37 | else | ||
| 38 |
6/12tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<false>():
✓ Branch 0 taken 906356 times.
✓ Branch 1 taken 103 times.
✓ Branch 6 taken 418951 times.
✓ Branch 7 taken 487405 times.
✓ Branch 8 taken 418951 times.
✓ Branch 9 taken 487508 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<false>():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
906459 | while (m > 1 && sgn_cross(cvh[m - 2], cvh[m - 1], (*this)[i]) < 0) --m; |
| 39 | // NOLINTNEXTLINE(misc-const-correctness) | ||
| 40 |
8/10tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<false>():
✓ Branch 2 taken 487477 times.
✓ Branch 3 taken 31 times.
tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<true>():
✓ Branch 2 taken 499940 times.
✓ Branch 3 taken 754 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<false>():
✗ Branch 2 not taken.
✗ Branch 3 not taken.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<true>():
✓ Branch 2 taken 20674088 times.
✓ Branch 3 taken 346939 times.
tifa_libs::cvh<long>& tifa_libs::cvh<long>::init<true>():
✓ Branch 2 taken 8761810 times.
✓ Branch 3 taken 341636 times.
|
31112675 | for (u32 i = n - 2, t = m; ~i; cvh[m++] = (*this)[i--]) |
| 41 | if CEXP (strict) | ||
| 42 |
18/18tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<true>():
✓ Branch 0 taken 928801 times.
✓ Branch 1 taken 48626 times.
✓ Branch 6 taken 477487 times.
✓ Branch 7 taken 451314 times.
✓ Branch 8 taken 477487 times.
✓ Branch 9 taken 499940 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<true>():
✓ Branch 0 taken 37495566 times.
✓ Branch 1 taken 2406879 times.
✓ Branch 6 taken 19228357 times.
✓ Branch 7 taken 18267209 times.
✓ Branch 8 taken 19228357 times.
✓ Branch 9 taken 20674088 times.
tifa_libs::cvh<long>& tifa_libs::cvh<long>::init<true>():
✓ Branch 0 taken 13947286 times.
✓ Branch 1 taken 2392704 times.
✓ Branch 6 taken 7578180 times.
✓ Branch 7 taken 6369106 times.
✓ Branch 8 taken 7578180 times.
✓ Branch 9 taken 8761810 times.
|
57219862 | while (m > t && sgn_cross(cvh[m - 2], cvh[m - 1], (*this)[i]) <= 0) --m; |
| 43 | else | ||
| 44 |
6/12tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<false>():
✓ Branch 0 taken 917415 times.
✓ Branch 1 taken 85 times.
✓ Branch 6 taken 430023 times.
✓ Branch 7 taken 487392 times.
✓ Branch 8 taken 430023 times.
✓ Branch 9 taken 487477 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<false>():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
917500 | while (m > t && sgn_cross(cvh[m - 2], cvh[m - 1], (*this)[i]) < 0) --m; |
| 45 | 689360 | cvh.resize(m - 1); | |
| 46 | 689360 | u32 p = 0; | |
| 47 |
8/10tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<false>():
✓ Branch 0 taken 125949 times.
✓ Branch 1 taken 31 times.
tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<true>():
✓ Branch 0 taken 44033 times.
✓ Branch 1 taken 754 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<false>():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<true>():
✓ Branch 0 taken 3045979 times.
✓ Branch 1 taken 346939 times.
tifa_libs::cvh<long>& tifa_libs::cvh<long>::init<true>():
✓ Branch 0 taken 2526822 times.
✓ Branch 1 taken 341636 times.
|
6432143 | flt_ (u32, i, 1, m - 1) |
| 48 |
4/10tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<false>():
✗ Branch 3 not taken.
✓ Branch 4 taken 125949 times.
tifa_libs::cvh<double>& tifa_libs::cvh<double>::init<true>():
✗ Branch 3 not taken.
✓ Branch 4 taken 44033 times.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<false>():
✗ Branch 3 not taken.
✗ Branch 4 not taken.
tifa_libs::cvh<long double>& tifa_libs::cvh<long double>::init<true>():
✗ Branch 3 not taken.
✓ Branch 4 taken 3045979 times.
tifa_libs::cvh<long>& tifa_libs::cvh<long>::init<true>():
✗ Branch 3 not taken.
✓ Branch 4 taken 2526822 times.
|
5742783 | if (cvh[i] < cvh[p]) p = i; |
| 49 | 689360 | rotate(cvh, begin(cvh) + p), this->vs = cvh; | |
| 50 | 689360 | return *this; | |
| 51 | 689360 | } | |
| 52 | // @return true if @p in convex hull (include border) | ||
| 53 | 340536 | CEXP bool contains(point<FP> CR p) CNE { | |
| 54 | 5331733 | auto it = lower_bound(begin(this->vs) + 1, end(this->vs), p, [&](point<FP> CR l, point<FP> CR r) NE { return is_pos(cross((*this)[0], l, r)); }) - 1; | |
| 55 | 340536 | auto next_it = this->next(it); | |
| 56 |
4/4tifa_libs::cvh<double>::contains(tifa_libs::point<double> const&) const::{lambda(tifa_libs::point<double> const&, tifa_libs::point<double> const&)#1}::operator()(tifa_libs::point<double> const&, tifa_libs::point<double> const&) const:
✓ Branch 3 taken 36850 times.
✓ Branch 4 taken 107 times.
tifa_libs::cvh<long double>::contains(tifa_libs::point<long double> const&) const::{lambda(tifa_libs::point<long double> const&, tifa_libs::point<long double> const&)#1}::operator()(tifa_libs::point<long double> const&, tifa_libs::point<long double> const&) const:
✓ Branch 3 taken 303430 times.
✓ Branch 4 taken 149 times.
|
340536 | if (auto res = sgn_cross(p, *it, *next_it); res) return ~res; |
| 57 |
6/8tifa_libs::cvh<double>::contains(tifa_libs::point<double> const&) const::{lambda(tifa_libs::point<double> const&, tifa_libs::point<double> const&)#1}::operator()(tifa_libs::point<double> const&, tifa_libs::point<double> const&) const:
✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 102 times.
tifa_libs::cvh<long double>::contains(tifa_libs::point<long double> const&) const::{lambda(tifa_libs::point<long double> const&, tifa_libs::point<long double> const&)#1}::operator()(tifa_libs::point<long double> const&, tifa_libs::point<long double> const&) const:
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
✓ Branch 6 taken 148 times.
✓ Branch 7 taken 1 time.
|
256 | else return !res && !is_pos(dot(p, *it, *next_it)); |
| 58 | } | ||
| 59 | template <bool get_index = false> | ||
| 60 | 366447 | CEXP auto diameter() CNE { | |
| 61 | 366447 | cu32 n = this->size(); | |
| 62 |
3/4auto tifa_libs::cvh<double>::diameter<false>() const:
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
auto tifa_libs::cvh<long double>::diameter<true>() const:
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 366075 times.
|
366447 | if (n <= 1) return std::conditional_t<get_index, edge_t<FP>, FP>{}; |
| 63 | 366099 | cu32 is = 0; | |
| 64 | 366099 | u32 js = 0; | |
| 65 |
4/4auto tifa_libs::cvh<double>::diameter<false>() const:
✓ Branch 0 taken 22437 times.
✓ Branch 1 taken 24 times.
auto tifa_libs::cvh<long double>::diameter<true>() const:
✓ Branch 0 taken 2595735 times.
✓ Branch 1 taken 366075 times.
|
2984271 | flt_ (u32, k, 1, n) |
| 66 |
4/4auto tifa_libs::cvh<double>::diameter<false>() const:
✓ Branch 3 taken 11151 times.
✓ Branch 4 taken 11286 times.
auto tifa_libs::cvh<long double>::diameter<true>() const:
✓ Branch 3 taken 1731402 times.
✓ Branch 4 taken 864333 times.
|
2618172 | if ((*this)[js] < (*this)[k]) js = k; |
| 67 | 366099 | u32 i = is, j = js; | |
| 68 | std::conditional_t<get_index, edge_t<FP>, FP> ret; | ||
| 69 | 366075 | if CEXP (get_index) ret = {dist_PP((*this)[i], (*this)[j]), i, j}; | |
| 70 | 24 | else ret = dist_PP((*this)[i], (*this)[j]); | |
| 71 | do { | ||
| 72 |
4/4auto tifa_libs::cvh<double>::diameter<false>() const:
✓ Branch 9 taken 22461 times.
✓ Branch 10 taken 22461 times.
auto tifa_libs::cvh<long double>::diameter<true>() const:
✓ Branch 9 taken 2961810 times.
✓ Branch 10 taken 2920980 times.
|
5927712 | (++((((*this)[this->next(i)] - (*this)[i]) ^ ((*this)[this->next(j)] - (*this)[j])) >= 0 ? j : i)) %= n; |
| 73 | 5882790 | if CEXP (get_index) ret = max(ret, edge_t<FP>{dist_PP((*this)[i], (*this)[j]), i, j}); | |
| 74 | 44922 | else ret = max(ret, dist_PP((*this)[i], (*this)[j])); | |
| 75 |
8/8auto tifa_libs::cvh<double>::diameter<false>() const:
✓ Branch 0 taken 44866 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 24 times.
auto tifa_libs::cvh<long double>::diameter<true>() const:
✓ Branch 0 taken 4824174 times.
✓ Branch 1 taken 1058616 times.
✓ Branch 2 taken 692541 times.
✓ Branch 3 taken 366075 times.
|
5927712 | } while (i != is || j != js); |
| 76 | 366099 | return ret; | |
| 77 | } | ||
| 78 | 20 | CEXP cvh& do_minkowski_sum(cvh<FP> CR r) NE { | |
| 79 | 20 | cu32 n = this->size(), m = r.size(); | |
| 80 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | retif_((!m) [[unlikely]], *this); |
| 81 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | retif_((!n) [[unlikely]], *this = r); |
| 82 | 40 | vec<point<FP>> res{(*this)[0] + r[0]}; | |
| 83 | 20 | res.reserve(n + m); | |
| 84 | 20 | u32 i = 0, j = 0; | |
| 85 |
4/4✓ Branch 0 taken 233451 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 233444 times.
✓ Branch 3 taken 7 times.
|
233464 | while (i < n && j < m) { |
| 86 | 233444 | auto dl = (*this)[this->next(i)] - (*this)[i], dr = r[r.next(j)] - r[j]; | |
| 87 | 233444 | bool f = !is_neg(dl ^ dr); | |
| 88 |
4/4✓ Branch 0 taken 116230 times.
✓ Branch 1 taken 117214 times.
✓ Branch 5 taken 116230 times.
✓ Branch 6 taken 117214 times.
|
233444 | res.push_back(res.back() + (f ? dl : dr)), ++(f ? i : j); |
| 89 | } | ||
| 90 |
2/2✓ Branch 7 taken 9 times.
✓ Branch 8 taken 20 times.
|
29 | while (i < n) res.push_back(res.back() + ((*this)[this->next(i)] - (*this)[i])), ++i; |
| 91 |
2/2✓ Branch 7 taken 17 times.
✓ Branch 8 taken 20 times.
|
37 | while (j < m) res.push_back(res.back() + (r[r.next(j)] - r[j])), ++j; |
| 92 | 20 | this->vs = res; | |
| 93 | 20 | return *this; | |
| 94 | 20 | } | |
| 95 | 581 | CEXP cvh& do_ins_CVHhP(line<FP> CR l) NE { | |
| 96 | 581 | cu32 n = this->size(); | |
| 97 | 581 | vec<point<FP>> cvc; | |
| 98 |
2/2✓ Branch 0 taken 15694 times.
✓ Branch 1 taken 581 times.
|
16275 | flt_ (u32, i, 0, n) { |
| 99 | 15694 | point p1 = (*this)[i], p2 = (*this)[this->next(i)]; | |
| 100 | 15694 | int d1 = l.toleft(p1), d2 = l.toleft(p2); | |
| 101 |
2/2✓ Branch 0 taken 7497 times.
✓ Branch 1 taken 8197 times.
|
15694 | if (d1 >= 0) cvc.push_back(p1); |
| 102 |
2/2✓ Branch 0 taken 1044 times.
✓ Branch 1 taken 14650 times.
|
15694 | if (d1 * d2 < 0) cvc.push_back(ins_LL({p1, p2}, l)); |
| 103 | } | ||
| 104 | 581 | this->vs = cvc; | |
| 105 | 1162 | return *this; | |
| 106 | 581 | } | |
| 107 | }; | ||
| 108 | |||
| 109 | } // namespace tifa_libs | ||
| 110 |