| Flutter Impeller |

Public Member Functions | Public Attributes | List of all members
impeller::CubicPathComponent Struct Reference

`#include <path_component.h>`

## Public Member Functions
| CubicPathComponent ()
| CubicPathComponent (const QuadraticPathComponent &q)
| CubicPathComponent (Point ap1, Point acp1, Point acp2, Point ap2)
Point | Solve (Scalar time) const
Point | SolveDerivative (Scalar time) const
void | AppendPolylinePoints (Scalar scale, std::vector< Point > &points) const
std::vector< Point > | Extrema () const
std::vector< QuadraticPathComponent > | ToQuadraticPathComponents (Scalar accuracy) const
CubicPathComponent | Subsegment (Scalar t0, Scalar t1) const
bool | operator== (const CubicPathComponent &other) const
std::optional< Vector2 > | GetStartDirection () const
std::optional< Vector2 > | GetEndDirection () const

## Public Attributes
Point | p1
Point | cp1
Point | cp2
Point | p2

## Detailed Description

Definition at line 94 of file path_component.h.

## Constructor & Destructor Documentation

## ◆ CubicPathComponent() [1/3]

impeller::CubicPathComponent::CubicPathComponent | ( |  | ) |
| inline

Definition at line 104 of file path_component.h.

104 {}

Referenced by Subsegment().

## ◆ CubicPathComponent() [2/3]

impeller::CubicPathComponent::CubicPathComponent | ( | const QuadraticPathComponent & | q | ) |
| inline explicit

Definition at line 106 of file path_component.h.

107 : p1(q.p1),
108 cp1(q.p1 + (q.cp - q.p1) * (2.0 / 3.0)),
109 cp2(q.p2 + (q.cp - q.p2) * (2.0 / 3.0)),
110 p2(q.p2) {}

## ◆ CubicPathComponent() [3/3]

impeller::CubicPathComponent::CubicPathComponent | ( | Point | ap1,
|  | Point | acp1,
|  | Point | acp2,
|  | Point | ap2
| ) |  |
| inline

Definition at line 112 of file path_component.h.

113 : p1(ap1), cp1(acp1), cp2(acp2), p2(ap2) {}

## Member Function Documentation

## ◆ AppendPolylinePoints()

void impeller::CubicPathComponent::AppendPolylinePoints | ( | Scalar | scale,
|  | std::vector< Point > & | points
| ) |  | const

Definition at line 188 of file path_component.cc.

190 {
191 auto quads = ToQuadraticPathComponents(.1);
192 for (const auto& quad : quads) {
193 quad.AppendPolylinePoints(scale, points);
194 }
195 }

References ToQuadraticPathComponents().

Referenced by impeller::testing::TEST().

## ◆ Extrema()

std::vector< Point > impeller::CubicPathComponent::Extrema | ( |  | ) | const

Definition at line 308 of file path_component.cc.

308 {
309 /*
310 * As described in: https://pomax.github.io/bezierinfo/#extremities
311 */
312 std::vector<Scalar> values;
313
314 CubicPathBoundingPopulateValues(values, p1.x, cp1.x, cp2.x, p2.x);
315 CubicPathBoundingPopulateValues(values, p1.y, cp1.y, cp2.y, p2.y);
316
317 std::vector<Point> points = {p1, p2};
318
319 for (const auto& value : values) {
320 points.emplace_back(Solve(value));
321 }
322
323 return points;
324 }

References cp1, cp2, impeller::CubicPathBoundingPopulateValues(), p1, p2, Solve(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::QuadraticPathComponent::Extrema(), impeller::Path::GetMinMaxCoveragePoints(), and impeller::testing::TEST().

## ◆ GetEndDirection()

std::optional< Vector2 > impeller::CubicPathComponent::GetEndDirection | ( |  | ) | const

Definition at line 339 of file path_component.cc.

339 {
340 if (p2 != cp2) {
341 return (p2 - cp2).Normalize();
342 }
343 if (p2 != cp1) {
344 return (p2 - cp1).Normalize();
345 }
346 if (p2 != p1) {
347 return (p2 - p1).Normalize();
348 }
349 return std::nullopt;
350 }

References cp1, cp2, p1, and p2.

Referenced by impeller::PathComponentEndDirectionVisitor::operator()().

## ◆ GetStartDirection()

std::optional< Vector2 > impeller::CubicPathComponent::GetStartDirection | ( |  | ) | const

Definition at line 326 of file path_component.cc.

326 {
327 if (p1 != cp1) {
328 return (p1 - cp1).Normalize();
329 }
330 if (p1 != cp2) {
331 return (p1 - cp2).Normalize();
332 }
333 if (p1 != p2) {
334 return (p1 - p2).Normalize();
335 }
336 return std::nullopt;
337 }

References cp1, cp2, p1, and p2.

Referenced by impeller::PathComponentStartDirectionVisitor::operator()().

## ◆ operator==()

bool impeller::CubicPathComponent::operator== | ( | const CubicPathComponent & | other | ) | const
| inline

Definition at line 133 of file path_component.h.

133 {
134 return p1 == other.p1 && cp1 == other.cp1 && cp2 == other.cp2 &&
135 p2 == other.p2;
136 }

References cp1, cp2, p1, and p2.

## ◆ Solve()

Point impeller::CubicPathComponent::Solve | ( | Scalar | time | ) | const

Definition at line 174 of file path_component.cc.

174 {
175 return {
176 CubicSolve(time, p1.x, cp1.x, cp2.x, p2.x), // x
177 CubicSolve(time, p1.y, cp1.y, cp2.y, p2.y), // y
178 };
179 }

References cp1, cp2, impeller::CubicSolve(), p1, p2, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by Extrema(), and Subsegment().

## ◆ SolveDerivative()

Point impeller::CubicPathComponent::SolveDerivative | ( | Scalar | time | ) | const

Definition at line 181 of file path_component.cc.

181 {
182 return {
183 CubicSolveDerivative(time, p1.x, cp1.x, cp2.x, p2.x), // x
184 CubicSolveDerivative(time, p1.y, cp1.y, cp2.y, p2.y), // y
185 };
186 }

References cp1, cp2, impeller::CubicSolveDerivative(), p1, p2, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

## ◆ Subsegment()

CubicPathComponent impeller::CubicPathComponent::Subsegment | ( | Scalar | t0,
|  | Scalar | t1
| ) |  | const

Definition at line 202 of file path_component.cc.

202 {
203 auto p0 = Solve(t0);
204 auto p3 = Solve(t1);
205 auto d = Lower();
206 auto scale = (t1 - t0) * (1.0 / 3.0);
207 auto p1 = p0 + scale * d.Solve(t0);
208 auto p2 = p3 - scale * d.Solve(t1);
209 return CubicPathComponent(p0, p1, p2, p3);
210 }

References CubicPathComponent(), p1, p2, and Solve().

Referenced by ToQuadraticPathComponents().

## ◆ ToQuadraticPathComponents()

std::vector< QuadraticPathComponent > impeller::CubicPathComponent::ToQuadraticPathComponents | ( | Scalar | accuracy | ) | const

Definition at line 213 of file path_component.cc.

213 {
214 std::vector<QuadraticPathComponent> quads;
215 // The maximum error, as a vector from the cubic to the best approximating
216 // quadratic, is proportional to the third derivative, which is constant
217 // across the segment. Thus, the error scales down as the third power of
218 // the number of subdivisions. Our strategy then is to subdivide `t` evenly.
219 //
220 // This is an overestimate of the error because only the component
221 // perpendicular to the first derivative is important. But the simplicity is
222 // appealing.
223
224 // This magic number is the square of 36 / sqrt(3).
225 // See: http://caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html
226 auto max_hypot2 = 432.0 * accuracy * accuracy;
227 auto p1x2 = 3.0 * cp1 - p1;
228 auto p2x2 = 3.0 * cp2 - p2;
229 auto p = p2x2 - p1x2;
230 auto err = p.Dot(p);
231 auto quad_count = std::max(1., ceil(pow(err / max_hypot2, 1. / 6.0)));
232 quads.reserve(quad_count);
233 for (size_t i = 0; i < quad_count; i++) {
234 auto t0 = i / quad_count;
235 auto t1 = (i + 1) / quad_count;
236 auto seg = Subsegment(t0, t1);
237 auto p1x2 = 3.0 * seg.cp1 - seg.p1;
238 auto p2x2 = 3.0 * seg.cp2 - seg.p2;
239 quads.emplace_back(
240 QuadraticPathComponent(seg.p1, ((p1x2 + p2x2) / 4.0), seg.p2));
241 }
242 return quads;
243 }

References cp1, cp2, impeller::TPoint< T >::Dot(), p1, p2, and Subsegment().

Referenced by AppendPolylinePoints().

## Member Data Documentation

## ◆ cp1

Point impeller::CubicPathComponent::cp1

Definition at line 98 of file path_component.h.

Referenced by Extrema(), GetEndDirection(), GetStartDirection(), operator==(), Solve(), SolveDerivative(), impeller::testing::TEST(), and ToQuadraticPathComponents().

## ◆ cp2

Point impeller::CubicPathComponent::cp2

Definition at line 100 of file path_component.h.

Referenced by Extrema(), GetEndDirection(), GetStartDirection(), operator==(), Solve(), SolveDerivative(), impeller::testing::TEST(), and ToQuadraticPathComponents().

## ◆ p1

Point impeller::CubicPathComponent::p1

Definition at line 96 of file path_component.h.

Referenced by Extrema(), GetEndDirection(), GetStartDirection(), operator==(), Solve(), SolveDerivative(), Subsegment(), impeller::testing::TEST(), and ToQuadraticPathComponents().

## ◆ p2

Point impeller::CubicPathComponent::p2

Definition at line 102 of file path_component.h.

Referenced by Extrema(), GetEndDirection(), GetStartDirection(), operator==(), Solve(), SolveDerivative(), Subsegment(), impeller::testing::TEST(), and ToQuadraticPathComponents().

The documentation for this struct was generated from the following files:

- impeller/geometry/path_component.h
- impeller/geometry/path_component.cc

impeller::TPoint::y
Type y
Definition: point.h:26
impeller::CubicPathComponent::Subsegment
CubicPathComponent Subsegment(Scalar t0, Scalar t1) const
Definition: path_component.cc:202
impeller::CubicPathComponent::p1
Point p1
Definition: path_component.h:96
impeller::CubicPathComponent::cp2
Point cp2
Definition: path_component.h:100
impeller::CubicPathComponent::Solve
Point Solve(Scalar time) const
Definition: path_component.cc:174
impeller::CubicPathBoundingPopulateValues
static void CubicPathBoundingPopulateValues(std::vector< Scalar > &values, Scalar p1, Scalar p2, Scalar p3, Scalar p4)
Definition: path_component.cc:253
impeller::TPoint::Dot
constexpr Type Dot(const TPoint &p) const
Definition: point.h:215
impeller::CubicSolveDerivative
static Scalar CubicSolveDerivative(Scalar t, Scalar p0, Scalar p1, Scalar p2, Scalar p3)
Definition: path_component.cc:44
impeller::CubicPathComponent::cp1
Point cp1
Definition: path_component.h:98
impeller::CubicSolve
static Scalar CubicSolve(Scalar t, Scalar p0, Scalar p1, Scalar p2, Scalar p3)
Definition: path_component.cc:33
impeller::CubicPathComponent::ToQuadraticPathComponents
std::vector< QuadraticPathComponent > ToQuadraticPathComponents(Scalar accuracy) const
Definition: path_component.cc:213
impeller::TPoint::x
Type x
Definition: point.h:25
impeller::CubicPathComponent::CubicPathComponent
CubicPathComponent()
Definition: path_component.h:104
impeller::CubicPathComponent::p2
Point p2
Definition: path_component.h:102