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  };
53 
54  // Parameters for drawing a rounded superellipse with equal radius size for
55  // all corners.
56  //
57  // This structure is used to define a quadrant of an arbitrary rounded
58  // superellipse.
59  struct Quadrant {
60  // The offset of the rounded superellipse's center from the origin.
61  //
62  // All other coordinates in this structure are relative to this point.
64 
65  // The scaling factor used to transform a normalized rounded superellipse
66  // back to its original, unnormalized shape.
67  //
68  // Normalization refers to adjusting the original curve, which may have
69  // asymmetrical corner sizes, into a symmetrical one by reducing the longer
70  // radius to match the shorter one. For instance, to draw a rounded
71  // superellipse with size (200, 300) and radii (20, 10), the function first
72  // draws a normalized RSE with size (100, 300) and radii (10, 10), then
73  // scales it by (2x, 1x) to restore the original proportions.
74  //
75  // Normalization also flips the curve to the first quadrant (positive x and
76  // y) if it originally resides in another quadrant. This affects the signs
77  // of `signed_scale`.
79 
80  // The parameters for the two octants that make up this quadrant after
81  // normalization.
84  };
85 
86  // The parameters for the four quadrants that make up the full contour.
87  //
88  // If `all_corners_same` is true, then only `top_right` is popularized.
93 
94  // If true, all corners are the same and only `top_right` is popularized.
96 
97  // Create a param for a rounded superellipse with the specific bounds and
98  // radii.
99  [[nodiscard]] static RoundSuperellipseParam MakeBoundsRadii(
100  const Rect& bounds,
101  const RoundingRadii& radii);
102 
103  [[nodiscard]] static RoundSuperellipseParam MakeBoundsRadius(
104  const Rect& bounds,
105  Scalar radius);
106 
107  // Returns whether this rounded superellipse contains the point.
108  //
109  // This method does not perform any prescreening such as comparing the point
110  // with the bounds, which is recommended for callers.
111  bool Contains(const Point& point) const;
112 
113  // Dispatch the path operations of this rounded superellipse to the receiver.
114  void Dispatch(PathReceiver& receiver) const;
115 
116  // A factor used to calculate the "gap", defined as the distance from the
117  // midpoint of the curved corners to the nearest sides of the bounding box.
118  //
119  // When the corner radius is symmetrical on both dimensions, the midpoint of
120  // the corner is where the circular arc intersects its quadrant bisector. When
121  // the corner radius is asymmetrical, since the corner can be considered
122  // "elongated" from a symmetrical corner, the midpoint is transformed in the
123  // same way.
124  //
125  // Experiments indicate that the gap is linear with respect to the corner
126  // radius on that dimension.
127  static constexpr Scalar kGapFactor = 0.29289321881f; // 1-cos(pi/4)
128 };
129 
130 } // namespace impeller
131 
132 #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)