MCPcopy Create free account
hub / github.com/VitalAudio/visage / arcTo

Method arcTo

visage_graphics/path.cpp:105–160  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

103 }
104
105 void Path::arcTo(float rx, float ry, float x_axis_rotation, bool large_arc, bool sweep_flag,
106 Point point, bool relative) {
107 rx = std::abs(rx);
108 ry = std::abs(ry);
109 if (rx == 0.0f || ry == 0.0f) {
110 lineTo(point);
111 return;
112 }
113
114 if (currentPath().points.empty())
115 addPoint(last_point_);
116
117 Point from = last_point_;
118 if (relative)
119 point += last_point_;
120
121 auto ellipse_rotation = Matrix::rotation(x_axis_rotation);
122 Point delta = ellipse_rotation.transposed() * (point - from);
123 float radius_ratio = rx / ry;
124 delta.y *= radius_ratio;
125
126 float length = delta.length();
127 if (length == 0.0f)
128 return;
129
130 float radius = std::max(length * 0.5f, rx);
131 float center_offset = std::sqrt(std::max(0.0f, radius * radius - length * length * 0.25f));
132 Point normal = Point(delta.y, -delta.x) / length;
133 if (large_arc != sweep_flag)
134 normal = -normal;
135
136 Point center = delta * 0.5f + normal * center_offset;
137 float arc_angle = 2.0f * std::asin(length * 0.5f / radius);
138
139 if (large_arc)
140 arc_angle = 2.0f * kPi - arc_angle;
141 if (!sweep_flag)
142 arc_angle = -arc_angle;
143
144 Point adjusted_radius = resolution_matrix_ * Point(rx, ry);
145 float max_radius = std::max(std::abs(adjusted_radius.x), std::abs(adjusted_radius.y));
146 float max_delta_radians = 2.0f * clampedACos(1.0f - error_tolerance_ / max_radius);
147 int num_points = std::ceil(std::abs(arc_angle) / max_delta_radians);
148
149 std::complex<float> position(-center.x, -center.y);
150 float angle_delta = arc_angle / num_points;
151 std::complex<float> rotation = std::polar(1.0f, angle_delta);
152
153 for (int i = 0; i < num_points; ++i) {
154 position *= rotation;
155 Point p = center + Point(position.real(), position.imag());
156 p.y /= radius_ratio;
157 p = ellipse_rotation * p + from;
158 addPoint(p);
159 }
160 }
161
162 static float parseNumber(const std::string& str, size_t& i, bool bit_flags = false) {

Callers 2

roundedRectangleFunction · 0.45
parseSvgPathMethod · 0.45

Calls 3

clampedACosFunction · 0.85
transposedMethod · 0.80
lengthMethod · 0.45

Tested by

no test coverage detected