Flutter Engine
 
Loading...
Searching...
No Matches
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
10
11namespace impeller {
12
13struct 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 {
47 size_t start_index = 0u;
48 size_t end_index = 0u;
49
50 size_t GetPointCount() const {
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.
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.
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
139namespace std {
140
141inline 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_
#define FML_DCHECK(condition)
Definition logging.h:122
Definition ref_ptr.h:261
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
Definition arc.h:141
size_t GetPointCount() const
Definition arc.h:50
impeller::Vector2 axis
Definition arc.h:46
impeller::Vector2 end
Definition arc.h:59
impeller::Vector2 start
Definition arc.h:58
size_t GetPointCount() const
Definition arc.cc:36
Quadrant quadrants[9]
Definition arc.h:86
size_t quadrant_count
Definition arc.h:63
Iteration ComputeIterations(size_t step_count, bool simplify_360=true) const
Definition arc.cc:102
Rect GetTightArcBounds() const
Definition arc.cc:59
constexpr bool IncludeCenter() const
Definition arc.h:110
constexpr bool IsFullCircle() const
Definition arc.h:114
const Size GetOvalSize() const
Returns the size of the oval bounds.
Definition arc.h:100
constexpr bool IsPerfectCircle() const
Definition arc.h:112
const Point GetOvalCenter() const
Returns the center of the oval bounds.
Definition arc.h:97
constexpr Degrees GetSweep() const
Definition arc.h:108
constexpr Degrees GetStart() const
Definition arc.h:106
const Rect & GetOvalBounds() const
Return the bounds of the oval in which this arc is inscribed.
Definition arc.h:94
Scalar degrees
Definition scalar.h:67
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
constexpr bool IsSquare() const
Returns true if width and height are equal and neither is NaN.
Definition rect.h:304
constexpr Point GetCenter() const
Get the center point as a |Point|.
Definition rect.h:382