Flutter Impeller
round_superellipse_param.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_ROUND_SUPERELLIPSE_PARAM_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_ROUND_SUPERELLIPSE_PARAM_H_
7 
13 
14 namespace impeller {
15 
16 // A utility struct that expands input parameters for a rounded superellipse to
17 // drawing variables.
19  // Parameters for drawing a square-like rounded superellipse.
20  //
21  // This structure is used to define an octant of an arbitrary rounded
22  // superellipse.
23  //
24  // A `se_n` of 0 means that the radius is 0, and this octant is a square
25  // of size `se_a` at `offset` and all other fields are ignored.
26  struct Octant {
27  // The offset of the square-like rounded superellipse's center from the
28  // origin.
29  //
30  // All other coordinates in this structure are relative to this point.
32 
33  // The semi-axis length of the superellipse.
35  // The degree of the superellipse.
36  //
37  // If this value is 0, then this octant is a square of size `se_a`.
39  // The range of the parameter "theta" used to define the superellipse curve.
40  //
41  // The "theta" is not the angle of the curve but the implicit parameter
42  // used in the curve's parametric equation.
44 
45  // The coordinate of the top left end of the circular arc, relative to the
46  // `offset` point.
48  // The center of the circular arc, relative to the `offset` point.
50  // The angular span of the circular arc, measured in radians.
52 
54  };
55 
56  // Parameters for drawing a rounded superellipse with equal radius size for
57  // all corners.
58  //
59  // This structure is used to define a quadrant of an arbitrary rounded
60  // superellipse.
61  struct Quadrant {
62  // The offset of the rounded superellipse's center from the origin.
63  //
64  // All other coordinates in this structure are relative to this point.
66 
67  // The scaling factor used to transform a normalized rounded superellipse
68  // back to its original, unnormalized shape.
69  //
70  // Normalization refers to adjusting the original curve, which may have
71  // asymmetrical corner sizes, into a symmetrical one by reducing the longer
72  // radius to match the shorter one. For instance, to draw a rounded
73  // superellipse with size (200, 300) and radii (20, 10), the function first
74  // draws a normalized RSE with size (100, 300) and radii (10, 10), then
75  // scales it by (2x, 1x) to restore the original proportions.
76  //
77  // Normalization also flips the curve to the first quadrant (positive x and
78  // y) if it originally resides in another quadrant. This affects the signs
79  // of `signed_scale`.
81 
82  // The parameters for the two octants that make up this quadrant after
83  // normalization.
86  };
87 
88  // The parameters for the four quadrants that make up the full contour.
89  //
90  // If `all_corners_same` is true, then only `top_right` is popularized.
95 
96  // If true, all corners are the same and only `top_right` is popularized.
98 
103 
104  // Create a param for a rounded superellipse with the specific bounds and
105  // radii.
106  [[nodiscard]] static RoundSuperellipseParam MakeBoundsRadii(
107  const Rect& bounds,
108  const RoundingRadii& radii);
109 
110  [[nodiscard]] static RoundSuperellipseParam MakeBoundsRadius(
111  const Rect& bounds,
112  Scalar radius);
113 
114  // Returns whether this rounded superellipse contains the point.
115  //
116  // This method does not perform any prescreening such as comparing the point
117  // with the bounds, which is recommended for callers.
118  bool Contains(const Point& point) const;
119 
120  // Dispatch the path operations of this rounded superellipse to the receiver.
121  void Dispatch(PathReceiver& receiver) const;
122 
123  // A factor used to calculate the "gap", defined as the distance from the
124  // midpoint of the curved corners to the nearest sides of the bounding box.
125  //
126  // When the corner radius is symmetrical on both dimensions, the midpoint of
127  // the corner is where the circular arc intersects its quadrant bisector. When
128  // the corner radius is asymmetrical, since the corner can be considered
129  // "elongated" from a symmetrical corner, the midpoint is transformed in the
130  // same way.
131  //
132  // Experiments indicate that the gap is linear with respect to the corner
133  // radius on that dimension.
134  static constexpr Scalar kGapFactor = 0.29289321881f; // 1-cos(pi/4)
135 };
136 
137 } // namespace impeller
138 
139 #endif // FLUTTER_IMPELLER_GEOMETRY_ROUND_SUPERELLIPSE_PARAM_H_
Collection of functions to receive path segments from the underlying path representation via the DlPa...
Definition: path_source.h:42
float Scalar
Definition: scalar.h:19
static RoundSuperellipseParam MakeBoundsRadii(const Rect &bounds, const RoundingRadii &radii)
void Dispatch(PathReceiver &receiver) const
bool Contains(const Point &point) const
static RoundSuperellipseParam MakeBoundsRadius(const Rect &bounds, Scalar radius)