1#include "internal/douglas_peucker.h"
11static inline float signed_left_dist(
const Point& A,
const Point& B,
const Point& P) {
12 const float dx = B.x - A.x, dy = B.y - A.y;
13 const float l = std::sqrt(dx * dx + dy * dy);
15 return std::sqrt(Point::distSq(P, A));
16 return ((P.y - A.y) * dx - (P.x - A.x) * dy) / l;
52 const std::vector<Point>& pts,
int lo,
int hi,
float eps,
float retract_eps,
53 float interior_sign, std::vector<uint8_t>& keep
58 const Point& A = pts[lo];
59 const Point& B = pts[hi];
61 float max_abs_dev = 0.0f;
62 float max_retract = 0.0f;
64 for (
int k = lo + 1; k < hi; ++k) {
65 const float d = signed_left_dist(A, B, pts[k]);
66 const float adev = std::fabs(d);
67 if (adev > max_abs_dev) {
73 const float retract = -interior_sign * d;
74 if (retract > max_retract)
75 max_retract = retract;
78 if (max_abs_dev <= eps && max_retract <= retract_eps)
82 dp_reduce(pts, lo, split, eps, retract_eps, interior_sign, keep);
83 dp_reduce(pts, split, hi, eps, retract_eps, interior_sign, keep);
104void dp_curve_reduction(
105 const std::vector<std::vector<Point>>& chains,
const std::vector<std::vector<uint8_t>>& fixed,
106 std::vector<std::vector<QuadBezier>>& results,
float eps
108 float retract_eps = std::min(eps, 0.5f);
110 for (
size_t i = 0; i < chains.size(); ++i) {
111 const std::vector<Point>& chain = chains[i];
112 const int n =
static_cast<int>(chain.size());
113 std::vector<QuadBezier> result;
115 results.push_back(result);
122 for (
int k = 0; k < n; ++k) {
123 const Point& p = chain[k];
124 const Point& q = chain[(k + 1) % n];
125 sa +=
static_cast<double>(p.x) * q.y -
static_cast<double>(q.x) * p.y;
127 const float interior_sign = (sa > 0.0) ? 1.0f : -1.0f;
131 std::vector<int> bounds;
133 for (
int k = 1; k < n - 1; ++k)
134 if (k <
static_cast<int>(fixed[i].size()) && fixed[i][k])
136 bounds.push_back(n - 1);
138 std::vector<uint8_t> keep(n, 0);
141 for (
size_t s = 0; s + 1 < bounds.size(); ++s)
142 dp_reduce(chain, bounds[s], bounds[s + 1], eps, retract_eps, interior_sign, keep);
146 for (
int k = 0; k < n; ++k) {
150 const Point& P = chain[prev];
151 const Point& Q = chain[k];
152 result.push_back({P, (P + Q) * 0.5f, Q});
156 results.push_back(result);