HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
bezier_point.hpp
1// Copyright Take Vos 2019, 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../geometry/geometry.hpp"
8#include "../utility/utility.hpp"
9#include "../macros.hpp"
10#include <vector>
11
12hi_export_module(hikogui.graphic_path.bezier_point);
13
14hi_export namespace hi { inline namespace v1 {
15
19hi_export struct bezier_point {
20 enum class Type { Anchor, QuadraticControl, CubicControl1, CubicControl2 };
21
22 Type type;
23 point2 p;
24
25 constexpr bezier_point(point2 const p, Type const type) noexcept : type(type), p(p) {}
26
27 constexpr bezier_point(float const x, float const y, Type const type) noexcept : bezier_point(point2{x, y}, type) {}
28
41 [[nodiscard]] constexpr static std::vector<bezier_point> normalizePoints(
42 std::vector<bezier_point>::const_iterator const begin,
43 std::vector<bezier_point>::const_iterator const end) noexcept
44 {
46
47 hi_axiom((end - begin) >= 2);
48
49 auto prev_it = end - 1;
50 auto prev_prev_it = end - 2;
51 for (auto it = begin; it != end; it++) {
52 switch (it->type) {
53 case bezier_point::Type::Anchor:
54 hi_axiom(prev_it->type != bezier_point::Type::CubicControl1);
55 r.push_back(*it);
56 break;
57
58 case bezier_point::Type::QuadraticControl:
59 if (it->type == bezier_point::Type::QuadraticControl) {
60 r.emplace_back(midpoint(prev_it->p, it->p), bezier_point::Type::Anchor);
61
62 } else {
63 hi_axiom(prev_it->type == bezier_point::Type::Anchor);
64 }
65 r.push_back(*it);
66 break;
67
68 case bezier_point::Type::CubicControl1:
69 r.push_back(*it);
70 break;
71
72 case bezier_point::Type::CubicControl2:
73 if (prev_it->type == bezier_point::Type::Anchor) {
74 hi_axiom(prev_prev_it->type == bezier_point::Type::CubicControl2);
75
76 r.emplace_back(reflect(prev_prev_it->p, prev_it->p), bezier_point::Type::CubicControl1);
77 } else {
78 hi_axiom(prev_it->type == bezier_point::Type::CubicControl1);
79 }
80 r.push_back(*it);
81 break;
82
83 default:
84 hi_no_default();
85 }
86
87 prev_prev_it = prev_it;
88 prev_it = it;
89 }
90
91 for (ssize_t i = 0; i < ssize(r); i++) {
92 if (r[i].type == bezier_point::Type::Anchor) {
93 std::rotate(r.begin(), r.begin() + i, r.end());
94 r.push_back(r.front());
95 return r;
96 }
97 }
98
99 // The result did not contain an anchor.
100 hi_no_default();
101 }
102
103 [[nodiscard]] constexpr friend bool operator==(bezier_point const&, bezier_point const&) noexcept = default;
104
107 [[nodiscard]] constexpr friend bezier_point operator*(transformer2 auto const& lhs, bezier_point const& rhs) noexcept
108 {
109 return {lhs * rhs.p, rhs.type};
110 }
111};
112
113}} // namespace hi::v1
@ end
Start from the end of the file.
@ begin
Start from the beginning of the file.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Definition bezier_point.hpp:19
constexpr friend bezier_point operator*(transformer2 auto const &lhs, bezier_point const &rhs) noexcept
Transform the point.
Definition bezier_point.hpp:107
static constexpr std::vector< bezier_point > normalizePoints(std::vector< bezier_point >::const_iterator const begin, std::vector< bezier_point >::const_iterator const end) noexcept
Definition bezier_point.hpp:41
Definition transform.hpp:61
T begin(T... args)
T emplace_back(T... args)
T end(T... args)
T front(T... args)
T push_back(T... args)
T rotate(T... args)