16 return p0 + t * (p1 - p0);
20 return (1 - t) * (1 - t) * p0 +
21 2 * (1 - t) * t * p1 +
29 return 2 * (1 - t) * (p1 - p0) +
38 return (1 - t) * (1 - t) * (1 - t) * p0 +
39 3 * (1 - t) * (1 - t) * t * p1 +
40 3 * (1 - t) * t * t * p2 +
49 return -3 * p0 * (1 - t) * (1 - t) +
50 p1 * (3 * (1 - t) * (1 - t) - 6 * (1 - t) * t) +
51 p2 * (6 * (1 - t) * t - 3 * t * t) +
63 std::vector<Point>& points)
const {
64 if (points.size() == 0 || points.back() !=
p2) {
77 return (
p1 -
p2).Normalize();
84 return (
p2 -
p1).Normalize();
102 constexpr
Scalar d = 0.67;
103 return x / (1.0 - d + sqrt(sqrt(pow(d, 4) + 0.25 * x * x)));
108 std::vector<Point>& points)
const {
110 points.emplace_back(point);
118 auto sqrt_tolerance = sqrt(tolerance);
123 auto cross = (
p2 -
p1).Cross(dd);
124 auto x0 = d01.
Dot(dd) * 1 / cross;
125 auto x2 = d12.Dot(dd) * 1 / cross;
126 auto scale = std::abs(cross / (hypot(dd.x, dd.y) * (x2 - x0)));
131 if (std::isfinite(
scale)) {
132 auto da = std::abs(a2 - a0);
133 auto sqrt_scale = sqrt(
scale);
134 if ((x0 < 0 && x2 < 0) || (x0 >= 0 && x2 >= 0)) {
135 val = da * sqrt_scale;
138 auto xmin = sqrt_tolerance / sqrt_scale;
144 auto uscale = 1 / (u2 - u0);
146 auto line_count = std::max(1., ceil(0.5 * val / sqrt_tolerance));
147 auto step = 1 / line_count;
148 for (
size_t i = 1; i < line_count; i += 1) {
150 auto a = a0 + (a2 - a0) * u;
164 return (
p1 -
cp).Normalize();
167 return (
p1 -
p2).Normalize();
174 return (
p2 -
cp).Normalize();
177 return (
p2 -
p1).Normalize();
198 std::vector<Point>& points)
const {
200 scale, [&points](
const Point& point) { points.emplace_back(point); });
212 auto scale = (t1 - t0) * (1.0 / 3.0);
213 auto p1 = p0 +
scale * d.Solve(t0);
214 auto p2 = p3 -
scale * d.Solve(t1);
220 constexpr
Scalar accuracy = 0.1;
232 auto max_hypot2 = 432.0 * accuracy * accuracy;
233 auto p1x2 = 3.0 *
cp1 -
p1;
234 auto p2x2 = 3.0 *
cp2 -
p2;
235 auto p = p2x2 - p1x2;
237 auto quad_count = std::max(1., ceil(pow(err / max_hypot2, 1. / 6.0)));
238 for (
size_t i = 0; i < quad_count; i++) {
239 auto t0 = i / quad_count;
240 auto t1 = (i + 1) / quad_count;
242 auto p1x2 = 3.0 * seg.cp1 - seg.p1;
243 auto p2x2 = 3.0 * seg.cp2 - seg.p2;
250 return (a > (
b - epsilon)) && (a < (
b + epsilon));
262 const Scalar a = 3.0 * (-p1 + 3.0 * p2 - 3.0 * p3 + p4);
263 const Scalar b = 6.0 * (p1 - 2.0 * p2 + p3);
264 const Scalar c = 3.0 * (p2 - p1);
275 if (t >= 0.0 && t <= 1.0) {
276 values.emplace_back(t);
281 Scalar b2Minus4AC = (
b *
b) - (4.0 * a * c);
283 if (b2Minus4AC < 0.0) {
287 Scalar rootB2Minus4AC = ::sqrt(b2Minus4AC);
295 Scalar q = (
b < 0) ? -(
b - rootB2Minus4AC) / 2 : -(
b + rootB2Minus4AC) / 2;
299 if (t >= 0.0 && t <= 1.0) {
300 values.emplace_back(t);
306 if (t >= 0.0 && t <= 1.0) {
307 values.emplace_back(t);
316 std::vector<Scalar> values;
321 std::vector<Point> points = {
p1,
p2};
323 for (
const auto& value : values) {
324 points.emplace_back(
Solve(value));
332 return (
p1 -
cp1).Normalize();
335 return (
p1 -
cp2).Normalize();
338 return (
p1 -
p2).Normalize();
345 return (
p2 -
cp2).Normalize();
348 return (
p2 -
cp1).Normalize();
351 return (
p2 -
p1).Normalize();