19 return A + (
B -
A) * t;
23 const auto in_X = [&curve](
size_t n) {
return curve[2*n]; };
24 const auto in_Y = [&curve](
size_t n) {
return curve[2*n + 1]; };
28 return {in_X(0), in_Y(0)};
31 return {in_X(3), in_Y(3)};
44 double one_minus_t = 1 - t;
45 double one_minus_t_squared = one_minus_t * one_minus_t;
46 double a = (one_minus_t_squared * one_minus_t);
47 double b = 3 * one_minus_t_squared * t;
48 double t_squared = t * t;
49 double c = 3 * one_minus_t * t_squared;
50 double d = t_squared * t;
52 return {
a * in_X(0) +
b * in_X(1) + c * in_X(2) +
d * in_X(3),
53 a * in_Y(0) +
b * in_Y(1) + c * in_Y(2) +
d * in_Y(3)};
59 double twoCurves[14]) {
62 const auto in_X = [&curve](
size_t n) {
return curve[2*n]; };
63 const auto in_Y = [&curve](
size_t n) {
return curve[2*n + 1]; };
64 const auto alpha_X = [&twoCurves](
size_t n) ->
double& {
return twoCurves[2*n]; };
65 const auto alpha_Y = [&twoCurves](
size_t n) ->
double& {
return twoCurves[2*n + 1]; };
66 const auto beta_X = [&twoCurves](
size_t n) ->
double& {
return twoCurves[2*n + 6]; };
67 const auto beta_Y = [&twoCurves](
size_t n) ->
double& {
return twoCurves[2*n + 7]; };
99 const double* offset_curve = yValues ? curve + 1 : curve;
100 const auto P = [&offset_curve](
size_t n) {
return offset_curve[2*n]; };
108 std::array<double, 4> results;
109 results[0] = -
P(0) + 3*
P(1) - 3*
P(2) +
P(3);
110 results[1] = 3*
P(0) - 6*
P(1) + 3*
P(2);
111 results[2] = -3*
P(0) + 3*
P(1);
118 DPoint(
double x_,
double y_) :
x{x_},
y{y_} {}
128 return {
a.
x +
b.x,
a.
y +
b.y};
132 return {
a.
x -
b.x,
a.
y -
b.y};
136 return {
s *
a.
x,
s *
a.
y};
140double pinTRange(
double t) {
156 const DPoint P0 = controlPoints[0],
157 P1 = controlPoints[1],
158 P2 = controlPoints[2],
159 P3 = controlPoints[3];
161 const DPoint
A = -P0 + 3*P1 - 3*P2 + P3,
162 B = 3*P0 - 6*P1 + 3*P2,
166 return Intersect(
A.x,
B.x,
C.x,
D.x,
A.y,
B.y,
C.y,
D.y, yIntercept, intersectionStorage);
171 double AY,
double BY,
double CY,
double DY,
172 float toIntersect,
float intersectionsStorage[3]) {
177 int intersectionCount = 0;
178 for (
double t : ts) {
179 const double pinnedT = pinTRange(t);
180 if (0 <= pinnedT && pinnedT <= 1) {
185 return {intersectionsStorage, intersectionCount};
190 float intersectionStorage[2]) {
192 const DPoint p0 = controlPoints[0],
193 p1 = controlPoints[1],
194 p2 = controlPoints[2];
197 const DPoint
A = p0 - 2 * p1 + p2,
204 return Intersect(
A.x,
B.x,
C.x,
A.y,
B.y,
C.y, yIntercept, intersectionStorage);
208 double AX,
double BX,
double CX,
double AY,
double BY,
double CY,
209 double yIntercept,
float intersectionStorage[2]) {
212 int intersectionCount = 0;
215 const double t0 = pinTRange(r0);
216 if (0 <= t0 && t0 <= 1) {
220 const double t1 = pinTRange(r1);
221 if (0 <= t1 && t1 <= 1 && t1 != t0) {
225 return SkSpan{intersectionStorage, intersectionCount};
static double interpolate(double A, double B, double t)
static constexpr float sk_double_to_float(double x)
SkSpan(Container &&) -> SkSpan< std::remove_pointer_t< decltype(std::data(std::declval< Container >()))> >
#define AX(width, name,...)
static std::array< double, 4 > ConvertToPolynomial(const double curve[8], bool yValues)
static std::array< double, 2 > EvalAt(const double curve[8], double t)
static SkSpan< const float > IntersectWithHorizontalLine(SkSpan< const SkPoint > controlPoints, float yIntercept, float intersectionStorage[3])
static void Subdivide(const double curve[8], double t, double twoCurves[14])
static SkSpan< const float > Intersect(double AX, double BX, double CX, double DX, double AY, double BY, double CY, double DY, float toIntersect, float intersectionsStorage[3])
static SkSpan< const float > IntersectWithHorizontalLine(SkSpan< const SkPoint > controlPoints, float yIntercept, float intersectionStorage[2])
static SkSpan< const float > Intersect(double AX, double BX, double CX, double AY, double BY, double CY, double yIntercept, float intersectionStorage[2])
static double EvalAt(double A, double B, double C, double D, double t)
static int RootsReal(double A, double B, double C, double D, double solution[3])
static RootResult Roots(double A, double B, double C)
static double EvalAt(double A, double B, double C, double t)
constexpr size_t size() const
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
constexpr Color operator-(T value, const Color &c)
constexpr Color operator+(T value, const Color &c)
constexpr Color operator*(T value, const Color &c)