7#include "../image/image.hpp"
8#include "../geometry/geometry.hpp"
9#include "../container/container.hpp"
10#include "../numeric/numeric.hpp"
11#include "../utility/utility.hpp"
13#include "bezier_point.hpp"
14#include "../macros.hpp"
22hi_export_module(hikogui.graphic_path.bezier_curve);
24hi_export
namespace hi {
inline namespace v1 {
30 enum class Type : uint8_t { None, Linear, Quadratic, Cubic };
79 return bezierPointAt(
P1,
P2, t);
81 return bezierPointAt(
P1,
C1,
P2, t);
83 return bezierPointAt(
P1,
C1,
C2,
P2, t);
100 return bezierTangentAt(
P1,
P2, t);
101 case Type::Quadratic:
102 return bezierTangentAt(
P1,
C1,
P2, t);
104 return bezierTangentAt(
P1,
C1,
C2,
P2, t);
119 case Type::Quadratic:
133 case Type::Quadratic:
182 return cross(normalize(
tangent), normalize(
PN));
192 auto const d = distance();
196 [[
nodiscard]] hi_force_inline
constexpr bool operator<(sdf_distance_result
const& rhs)
const noexcept
226 auto const ts = solveTForNormalsIntersectingPoint(P);
228 t = std::clamp(t, 0.0f, 1.0f);
230 auto const PN = P -
pointAt(t);
231 auto const sq_distance = squared_hypot(PN);
232 if (sq_distance <
nearest.sq_distance) {
235 nearest.sq_distance = sq_distance;
298 case Type::Quadratic:
316 auto const[a, b] =
split(0.5f);
341 case Type::Quadratic:
362 if (lhs.type != rhs.type) {
366 case bezier_curve::Type::Linear:
367 return (lhs.P1 == rhs.P1) && (lhs.P2 == rhs.P2);
368 case bezier_curve::Type::Quadratic:
369 return (lhs.P1 == rhs.P1) && (lhs.C1 == rhs.C1) && (lhs.P2 == rhs.P2);
370 case bezier_curve::Type::Cubic:
371 return (lhs.P1 == rhs.P1) && (lhs.C1 == rhs.C1) && (lhs.C2 == rhs.C2) && (lhs.P2 == rhs.P2);
377 [[
nodiscard]]
friend bezier_curve operator*(transformer2
auto const& lhs, bezier_curve
const& rhs)
noexcept
379 return {rhs.type, lhs * rhs.P1, lhs * rhs.C1, lhs * rhs.C2, lhs * rhs.P2};
386 return {rhs.type, rhs.P2, rhs.C2, rhs.C1, rhs.P1};
397 for (
auto const& curve : v) {
406[[
nodiscard]]
constexpr std::optional<std::vector<std::pair<float, float>>>
409 auto xValues = solveCurvesXByY(v, y);
435constexpr void fillPartialPixels(std::span<uint8_t>
row,
ssize_t const i,
float const startX,
float const endX)
noexcept
443constexpr void fillFullPixels(std::span<uint8_t>
row,
ssize_t const start,
ssize_t const size)
noexcept
446 auto const end = start + size;
461 auto u64p =
reinterpret_cast<uint64_t *
>(
u8p);
462 auto const *
const u64end =
reinterpret_cast<uint64_t
const *
>(hi::floor(
u8end,
sizeof(uint64_t)));
464 *(
u64p++) += 0x3333333333333333ULL;
468 u8p =
reinterpret_cast<uint8_t *
>(
u64p);
478constexpr void fillRowSpan(std::span<uint8_t>
row,
float const startX,
float const endX)
noexcept
503 for (
float y =
rowY + 0.1f; y < (
rowY + 1); y += 0.2f) {
513 for (
auto const& span :
spans) {
514 fillRowSpan(
row, span.first, span.second);
537 return nearest.signed_distance();
555 auto type = bezier_curve::Type::None;
561 switch (
point.type) {
562 case bezier_point::Type::Anchor:
564 case bezier_curve::Type::None:
566 type = bezier_curve::Type::Linear;
568 case bezier_curve::Type::Linear:
571 type = bezier_curve::Type::Linear;
573 case bezier_curve::Type::Quadratic:
576 type = bezier_curve::Type::Linear;
578 case bezier_curve::Type::Cubic:
581 type = bezier_curve::Type::Linear;
587 case bezier_point::Type::QuadraticControl:
589 type = bezier_curve::Type::Quadratic;
591 case bezier_point::Type::CubicControl1:
593 type = bezier_curve::Type::Cubic;
595 case bezier_point::Type::CubicControl2:
597 hi_assert(type == bezier_curve::Type::Cubic);
642 for (
auto const& curve :
contour) {
656 }
else if (r.
back().P2 == curve.
P1) {
695 for (
auto y = 0
_uz; y < image.height(); y++) {
696 detail::fillRow(image[y], y,
curves);
708 auto const y =
static_cast<float>(
row_nr);
709 for (
auto column_nr = 0
_uz; column_nr != image.width(); ++column_nr) {
710 auto const x =
static_cast<float>(column_nr);
711 row[column_nr] = detail::generate_sdf_r8_pixel(point2(x, y),
curves);
@ end
Start from the end of the file.
@ begin
Start from the beginning of the file.
line_join_style
The way two lines should be joined.
Definition line_join_style.hpp:22
@ miter
The outer edge of both lines are extended until they meet to form a sharp corner.
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
The HikoGUI namespace.
Definition recursive_iterator.hpp:15
hi_inline std::optional< point2 > getIntersectionPoint(point2 A1, point2 A2, point2 B1, point2 B2) noexcept
Definition bezier.hpp:291
hi_inline lean_vector< float > bezierFindX(point2 P1, point2 P2, float y) noexcept
Definition bezier.hpp:179
std::ptrdiff_t ssize_t
Signed size/index into an array.
Definition misc.hpp:32
constexpr std::vector< bezier_curve > makeContourFromPoints(std::vector< bezier_point >::const_iterator begin, std::vector< bezier_point >::const_iterator end) noexcept
Make a contour of Bezier curves from a list of points.
Definition bezier_curve.hpp:549
hi_inline float bezierFlatness(point2 P1, point2 P2) noexcept
Definition bezier.hpp:246
hi_inline lean_vector< float > bezierFindTForNormalsIntersectingPoint(point2 P1, point2 P2, point2 P) noexcept
Find t on the line P1->P2 which is closest to P.
Definition bezier.hpp:139
unit< si_length_tag, double, std::ratio< 254, 720 '000 >::type > points
Points: 1/72 inch.
Definition units.hpp:180
constexpr std::vector< bezier_curve > makeInverseContour(std::vector< bezier_curve > const &contour) noexcept
Inverse a contour.
Definition bezier_curve.hpp:613
hi_inline std::optional< point2 > getExtrapolatedIntersectionPoint(point2 A1, point2 A2, point2 B1, point2 B2) noexcept
Definition bezier.hpp:322
constexpr std::vector< bezier_curve > makeParallelContour(std::vector< bezier_curve > const &contour, float offset, hi::line_join_style line_join_style, float tolerance) noexcept
Definition bezier_curve.hpp:635
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:378
Lean-vector with (SVO) short-vector-optimization.
Definition lean_vector.hpp:35
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector2.hpp:26
Definition bezier_curve.hpp:29
point2 pointAt(float const t) const noexcept
Definition bezier_curve.hpp:75
point2 P2
Last point.
Definition bezier_curve.hpp:36
void subdivideUntilFlat_impl(std::vector< bezier_curve > &r, float const minimumFlatness) const noexcept
Definition bezier_curve.hpp:311
std::vector< bezier_curve > subdivideUntilFlat(float const tolerance) const noexcept
Definition bezier_curve.hpp:326
bezier_curve(point2 const P1, point2 const C1, point2 const P2) noexcept
Definition bezier_curve.hpp:50
std::pair< bezier_curve, bezier_curve > linearSplit(float const t) const noexcept
Definition bezier_curve.hpp:281
constexpr vector2 tangentAt(float const t) const noexcept
Definition bezier_curve.hpp:96
sdf_distance_result sdf_distance(point2 P) const noexcept
Find the distance from the point to the curve.
Definition bezier_curve.hpp:222
bezier_curve(Type const type, point2 const P1, point2 const C1, point2 const C2, point2 const P2) noexcept
Definition bezier_curve.hpp:63
std::pair< bezier_curve, bezier_curve > split(float const t) const noexcept
Definition bezier_curve.hpp:293
point2 C2
Control point.
Definition bezier_curve.hpp:35
std::pair< bezier_curve, bezier_curve > quadraticSplit(float const t) const noexcept
Definition bezier_curve.hpp:266
friend bezier_curve operator~(bezier_curve const &rhs) noexcept
Definition bezier_curve.hpp:384
point2 C1
Control point.
Definition bezier_curve.hpp:34
bezier_curve toParallelLine(float const offset) const noexcept
Definition bezier_curve.hpp:354
bezier_curve(point2 const P1, point2 const C1, point2 const C2, point2 const P2) noexcept
Definition bezier_curve.hpp:56
point2 P1
First point.
Definition bezier_curve.hpp:33
float flatness() const noexcept
Definition bezier_curve.hpp:336
lean_vector< float > solveXByY(float const y) const noexcept
Definition bezier_curve.hpp:114
std::pair< bezier_curve, bezier_curve > cubicSplit(float const t) const noexcept
Definition bezier_curve.hpp:247
Definition bezier_curve.hpp:142
vector2 PN
The vector between P and N.
Definition bezier_curve.hpp:145
float t
Linear position on the curve-segment, 0.0 and 1.0 are end-points.
Definition bezier_curve.hpp:151
hi_force_inline constexpr float orthogonality() const noexcept
The orthogonality of the line PN and the tangent of the curve at N.
Definition bezier_curve.hpp:166
float sq_distance
The square distance between P and N.
Definition bezier_curve.hpp:155
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
A non-owning 2D pixel-based image.
Definition pixmap_span.hpp:34
T emplace_back(T... args)