| Flutter Impeller |

arc.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_GEOMETRY_ARC_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_ARC_H_
7
8 #include "flutter/impeller/geometry/rect.h"
9 #include "flutter/impeller/geometry/scalar.h"
10
11 namespace impeller {
12
13 struct Arc {
14 /// A structure to describe the iteration through a set of angle vectors
15 /// in a |Trigs| structure to render the points along an arc. The start
16 /// and end vectors and each iteration's axis vector are all unit vectors
17 /// that point in the direction of the point on the circle to be emitted.
18 ///
19 /// Each vector should be rendered by multiplying it by the radius of the
20 /// circle, or in the case of a stroked arc, by the inner and outer radii
21 /// of the sides of the stroke.
22 ///
23 /// - The start vector will always be rendered first.
24 /// - Then each quadrant will be iterated by composing the trigs vectors
25 /// with the given axis vector, iterating from the start index (inclusive)
26 /// to the end index (exclusive) of the vector of |Trig| values.
27 /// - Finally the end vector will be rendered.
28 /// For example:
29 /// Insert(arc_iteration.start * radius);
30 /// for (size_t i = 0u; i < arc_iteration.quadrant_count; i++) {
31 /// Quadrant quadrant = arc_iteration.quadrants[i];
32 /// for (j = quadrant.start_index; j < quadrant.end_index; j++) {
33 /// Insert(trigs[j] * quadrant.axis * radius);
34 /// }
35 /// }
36 /// Insert(arc_iteration.end * radius);
37 ///
38 /// The rendering routine may adjust the manner/order in which those vertices
39 /// are inserted into the vertex buffer to optimally match the vertex triangle
40 /// mode it plans to use, but the description above represents the basic
41 /// technique to compute the points along the actual curve.
42 struct Iteration {
43 // The axis to multiply by each |Trig| value and the half-open [start, end)
44 // range of indices into the associated |Trig| vector over which to compute.
45 struct Quadrant {
46 impeller::Vector2 axis;
47 size_t start_index = 0u;
48 size_t end_index = 0u;
49
50 size_t GetPointCount() const {
51 FML_DCHECK(start_index < end_index);
52 return end_index - start_index;
53 }
54 };
55
56 // The true begin and end angles of the arc, expressed as unit direction
57 // vectors.
58 impeller::Vector2 start;
59 impeller::Vector2 end;
60
61 // The variable number of quadrants that have to be iterated and
62 // cross-referenced with values in a |Trigs| object.
63 size_t quadrant_count = 0u;
64
65 // Normally, we have at most 5 |Quadrant| entries when an arc starts
66 // and ends in the same quadrant with the start angle later in the
67 // quadrant than the end angle.
68 //
69 // Worst case:
70 // - First iteration goes from the start angle to the end of that quadrant.
71 // - Then 3 full iterations for the 3 other full quarter circles.
72 // - Then a last iteration that goes from the start of that quadrant to the
73 // end angle.
74 //
75 // However, when we have an arc that sweeps past a full circle, then we
76 // can have up to 9 |Quadrant| entries. The extra quadrants are only
77 // interesting in the case where the arc is stroked and we are including
78 // the center. Such an arc should look like a complete circle with an
79 // additional pie sliced cut into it, but not removed. Expressing that
80 // case with one continuous path may require up to 7 full quadrants and
81 // 2 partial quadrants for 9 total quadrants in this degenerate stroking
82 // case.
83 //
84 // We can also have 0 quadrants for arcs that are smaller than the
85 // step size of the pixel-radius |Trigs| vector.
86 Quadrant quadrants[9];
87
88 size_t GetPointCount() const;
89 };
90
91 Arc(const Rect& bounds, Degrees start, Degrees sweep, bool include_center);
92
93 /// Return the bounds of the oval in which this arc is inscribed.
94 const Rect& GetOvalBounds() const { return bounds_; }
95
96 /// Returns the center of the oval bounds.
97 const Point GetOvalCenter() const { return bounds_.GetCenter(); }
98
99 /// Returns the size of the oval bounds.
100 const Size GetOvalSize() const { return bounds_.GetSize(); }
101
102 /// Return the tight bounds of the arc taking into account its specific
103 /// geometry such as the start and end angles and the center (if included).
104 Rect GetTightArcBounds() const;
105
106 constexpr Degrees GetStart() const { return start_; }
107
108 constexpr Degrees GetSweep() const { return sweep_; }
109
110 constexpr bool IncludeCenter() const { return include_center_; }
111
112 constexpr bool IsPerfectCircle() const { return bounds_.IsSquare(); }
113
114 constexpr bool IsFullCircle() const { return sweep_.degrees >= 360.0f; }
115
116 /// Return an |ArcIteration| that explains how to generate vertices for
117 /// the arc with the indicated number of steps in each full quadrant.
118 /// The step_count is typically chosen based on the size of the bounds
119 /// and the scale at which the arc is being drawn and so the computation
120 /// of the step_count requirements is left to the caller.
121 ///
122 /// If the sweep is more than 360 degrees then the code may simplify
123 /// the iteration to a simple circle, but only if the simplify_360
124 /// parameter is true.
125 Iteration ComputeIterations(size_t step_count,
126 bool simplify_360 = true) const;
127
128 private:
129 Rect bounds_;
130 Degrees start_;
131 Degrees sweep_;
132 bool include_center_;
133
134 static const Iteration ComputeCircleArcIterations(size_t step_count);
135 };
136
137 } // namespace impeller
138
139 namespace std {
140
141 inline std::ostream& operator<<(std::ostream& out, const impeller::Arc& a) {
142 out << "Arc(" << a.GetOvalBounds() << ", " << a.GetStart() << " + "
143 << a.GetSweep()
144 << (a.IncludeCenter() ? ", with center)" : ", without center)");
145 return out;
146 }
147
148 } // namespace std
149
150 #endif // FLUTTER_IMPELLER_GEOMETRY_ARC_H_
impeller
Definition: allocation.cc:12
std
Definition: comparable.h:95
std::operator<<
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
Definition: arc.h:141
rect.h
scalar.h
impeller::Arc::Iteration::Quadrant
Definition: arc.h:45
impeller::Arc::Iteration::Quadrant::GetPointCount
size_t GetPointCount() const
Definition: arc.h:50
impeller::Arc::Iteration::Quadrant::axis
impeller::Vector2 axis
Definition: arc.h:46
impeller::Arc::Iteration::Quadrant::start_index
size_t start_index
Definition: arc.h:47
impeller::Arc::Iteration::Quadrant::end_index
size_t end_index
Definition: arc.h:48
impeller::Arc::Iteration
Definition: arc.h:42
impeller::Arc::Iteration::end
impeller::Vector2 end
Definition: arc.h:59
impeller::Arc::Iteration::start
impeller::Vector2 start
Definition: arc.h:58
impeller::Arc::Iteration::GetPointCount
size_t GetPointCount() const
Definition: arc.cc:36
impeller::Arc::Iteration::quadrants
Quadrant quadrants[9]
Definition: arc.h:86
impeller::Arc::Iteration::quadrant_count
size_t quadrant_count
Definition: arc.h:63
impeller::Arc
Definition: arc.h:13
impeller::Arc::ComputeIterations
Iteration ComputeIterations(size_t step_count, bool simplify_360=true) const
Definition: arc.cc:102
impeller::Arc::Arc
Arc(const Rect &bounds, Degrees start, Degrees sweep, bool include_center)
Definition: arc.cc:9
impeller::Arc::GetTightArcBounds
Rect GetTightArcBounds() const
Definition: arc.cc:59
impeller::Arc::IncludeCenter
constexpr bool IncludeCenter() const
Definition: arc.h:110
impeller::Arc::IsFullCircle
constexpr bool IsFullCircle() const
Definition: arc.h:114
impeller::Arc::GetOvalSize
const Size GetOvalSize() const
Returns the size of the oval bounds.
Definition: arc.h:100
impeller::Arc::IsPerfectCircle
constexpr bool IsPerfectCircle() const
Definition: arc.h:112
impeller::Arc::GetOvalBounds
const Rect & GetOvalBounds() const
Return the bounds of the oval in which this arc is inscribed.
Definition: arc.h:94
impeller::Arc::GetOvalCenter
const Point GetOvalCenter() const
Returns the center of the oval bounds.
Definition: arc.h:97
impeller::Arc::GetSweep
constexpr Degrees GetSweep() const
Definition: arc.h:108
impeller::Arc::GetStart
constexpr Degrees GetStart() const
Definition: arc.h:106
impeller::Degrees
Definition: scalar.h:66
impeller::Degrees::degrees
Scalar degrees
Definition: scalar.h:67
impeller::TPoint< Scalar >
impeller::TRect< Scalar >
impeller::TRect::GetSize
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
Definition: rect.h:327
impeller::TRect::IsSquare
constexpr bool IsSquare() const
Returns true if width and height are equal and neither is NaN.
Definition: rect.h:304
impeller::TRect::GetCenter
constexpr Point GetCenter() const
Get the center point as a |Point|.
Definition: rect.h:382
impeller::TSize< Scalar >
start
const size_t start
Definition: tessellator_libtess.cc:62