GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 96.6% 57 / 0 / 59
Functions: 93.5% 29 / 0 / 31
Branches: 93.8% 30 / 0 / 32

src/geo2d/ds/po/lib.hpp
Line Branch Exec Source
1 #pragma once
2
3 #include "../../../edh/discretization/lib.hpp"
4 #include "../../../math/kahan/lib.hpp"
5 #include "../../cross/lib.hpp"
6 #include "../../dis/pp/lib.hpp"
7
8 namespace tifa_libs {
9
10 template <class FP>
11 struct polygon {
12 vec<point<FP>> vs;
13
14 CEXP polygon() = default;
15 1534816 CEXPE polygon(u32 sz) NE : vs(sz) {}
16 40552 CEXP polygon(itl<point<FP>> vs_) NE : vs(vs_) {}
17 10038 CEXP polygon(spn<point<FP>> vs_) NE : vs(begin(vs_), end(vs_)) {}
18
19 104 friend auto& operator>>(istream_c auto& is, polygon& p) NE {
20
2/2
✓ Branch 6 taken 3222 times.
✓ Branch 7 taken 104 times.
3326 for (auto& i : p.vs) is >> i;
21 104 return is;
22 }
23 friend auto& operator<<(ostream_c auto& os, polygon CR p) NE {
24 retif_((p.vs.empty()) [[unlikely]], os);
25 for (auto it = begin(p.vs); it != end(p.vs) - 1; ++it) os << *it << ' ';
26 return os << p.vs.back();
27 }
28 371330134 ND CEXP u32 size() CNE { return (u32)vs.size(); }
29 169297685 CEXP point<FP>& operator[](u32 x) NE { return vs[x]; }
30 618176851 CEXP point<FP> CR operator[](u32 x) CNE { return vs[x]; }
31 CEXP polygon& resort() NE {
32 sort(vs);
33 return *this;
34 }
35 767876 CEXP polygon& reunique() NE {
36 767876 vs = uniq(vs);
37 767876 return *this;
38 }
39 CEXP auto prev(TPN vec<point<FP>>::const_iterator it) CNE {
40 if (it == begin(vs)) it = end(vs);
41 return --it;
42 }
43
4/4
tifa_libs::polygon<double>::next(__gnu_cxx::__normal_iterator<tifa_libs::point<double> const*, std::vector<tifa_libs::point<double>, std::allocator<tifa_libs::point<double> > > >) const:
✓ Branch 3 taken 368 times.
✓ Branch 4 taken 36589 times.
tifa_libs::polygon<long double>::next(__gnu_cxx::__normal_iterator<tifa_libs::point<long double> const*, std::vector<tifa_libs::point<long double>, std::allocator<tifa_libs::point<long double> > > >) const:
✓ Branch 3 taken 66 times.
✓ Branch 4 taken 303513 times.
340536 CEXP auto next(TPN vec<point<FP>>::const_iterator it) CNE { retif_((++it == end(vs)) [[unlikely]], begin(vs), it); }
44 ND CEXP u32 prev(u32 idx) CNE { retif_((idx == 0) [[unlikely]], size() - 1, idx - 1); }
45
4/4
tifa_libs::polygon<double>::next(unsigned int) const:
✓ Branch 1 taken 8078 times.
✓ Branch 2 taken 479315 times.
tifa_libs::polygon<long double>::next(unsigned int) const:
✓ Branch 1 taken 73294358 times.
✓ Branch 2 taken 224600267 times.
298382018 ND CEXP u32 next(u32 idx) CNE { retif_((idx + 1 == size()) [[unlikely]], 0, idx + 1); }
46 111 CEXP FP circum() CNE {
47 111 kahan<FP> ret = dist_PP(vs.back(), vs.front());
48
2/2
✓ Branch 5 taken 14624 times.
✓ Branch 6 taken 111 times.
14735 flt_ (u32, i, 0, size() - 1) ret += dist_PP(vs[i], vs[i + 1]);
49 111 return ret;
50 }
51 1523 CEXP FP area2() CNE {
52
3/4
tifa_libs::polygon<double>::area2() const:
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 807 times.
tifa_libs::polygon<long double>::area2() const:
✗ Branch 1 not taken.
✓ Branch 2 taken 688 times.
1523 retif_((size() < 3) [[unlikely]], 0);
53 1495 kahan<FP> ret = vs.back() ^ vs.front();
54
4/4
tifa_libs::polygon<double>::area2() const:
✓ Branch 5 taken 11770 times.
✓ Branch 6 taken 807 times.
tifa_libs::polygon<long double>::area2() const:
✓ Branch 5 taken 158300 times.
✓ Branch 6 taken 688 times.
171565 flt_ (u32, i, 0, size() - 1) ret += vs[i] ^ vs[i + 1];
55 1495 return ret;
56 }
57 1523 CEXP FP area() CNE {
58 static_assert(std::floating_point<FP>);
59 1523 return area2() * (FP).5;
60 }
61 32 ND CEXP bool is_convex() CNE {
62 32 arr<bool, 2> flag{false, false};
63 32 cu32 n = size();
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 retif_((n < 3) [[unlikely]], true);
65
2/2
✓ Branch 4 taken 695 times.
✓ Branch 5 taken 13 times.
708 for (u32 i = 0, j = next(i), k = next(j); i < n; ++i, j = next(j), k = next(k)) {
66
2/2
✓ Branch 4 taken 626 times.
✓ Branch 5 taken 69 times.
695 if (auto sgn = sgn_cross(vs[i], vs[j], vs[k]); sgn) flag[(sgn + 1) / 2] = true;
67
6/6
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 673 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 19 times.
✓ Branch 7 taken 676 times.
695 if (flag[0] && flag[1]) return false;
68 }
69 13 return true;
70 }
71 // @return nullopt if @p on board of polygon, otherwise winding number
72 CEXP auto winding(point<FP> CR p) CNE {
73 std::optional<u32> ret{0};
74 flt_ (u32, i, 0, size()) {
75 auto &&u = vs[i], &&v = vs[next(i)];
76 if (!sgn_cross(p, u, v) && !sgn_dot(p, u, v)) {
77 ret = std::nullopt;
78 return ret;
79 }
80 if (is_zero(u.y - v.y)) continue;
81 if (is_lt(u.y, v.y) && !is_pos(u, v, p)) continue;
82 if (is_gt(u.y, v.y) && !is_neg(u, v, p)) continue;
83 if (is_lt(u.y, p.y) && !is_lt(v.y, p.y)) ++ret.value();
84 if (!is_lt(u.y, p.y) && is_lt(v.y, p.y)) --ret.value();
85 }
86 return ret;
87 }
88 };
89
90 } // namespace tifa_libs
91