| 1165 | } |
| 1166 | |
| 1167 | void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments) |
| 1168 | { |
| 1169 | if (radius < 0.5f) |
| 1170 | { |
| 1171 | _Path.push_back(center); |
| 1172 | return; |
| 1173 | } |
| 1174 | |
| 1175 | if (num_segments > 0) |
| 1176 | { |
| 1177 | _PathArcToN(center, radius, a_min, a_max, num_segments); |
| 1178 | return; |
| 1179 | } |
| 1180 | |
| 1181 | // Automatic segment count |
| 1182 | if (radius <= _Data->ArcFastRadiusCutoff) |
| 1183 | { |
| 1184 | const bool a_is_reverse = a_max < a_min; |
| 1185 | |
| 1186 | // We are going to use precomputed values for mid samples. |
| 1187 | // Determine first and last sample in lookup table that belong to the arc. |
| 1188 | const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f); |
| 1189 | const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f); |
| 1190 | |
| 1191 | const int a_min_sample = a_is_reverse ? (int)ImFloorSigned(a_min_sample_f) : (int)ImCeil(a_min_sample_f); |
| 1192 | const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloorSigned(a_max_sample_f); |
| 1193 | const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0); |
| 1194 | |
| 1195 | const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; |
| 1196 | const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; |
| 1197 | const bool a_emit_start = ImAbs(a_min_segment_angle - a_min) >= 1e-5f; |
| 1198 | const bool a_emit_end = ImAbs(a_max - a_max_segment_angle) >= 1e-5f; |
| 1199 | |
| 1200 | _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0))); |
| 1201 | if (a_emit_start) |
| 1202 | _Path.push_back(ImVec2(center.x + ImCos(a_min) * radius, center.y + ImSin(a_min) * radius)); |
| 1203 | if (a_mid_samples > 0) |
| 1204 | _PathArcToFastEx(center, radius, a_min_sample, a_max_sample, 0); |
| 1205 | if (a_emit_end) |
| 1206 | _Path.push_back(ImVec2(center.x + ImCos(a_max) * radius, center.y + ImSin(a_max) * radius)); |
| 1207 | } |
| 1208 | else |
| 1209 | { |
| 1210 | const float arc_length = ImAbs(a_max - a_min); |
| 1211 | const int circle_segment_count = _CalcCircleAutoSegmentCount(radius); |
| 1212 | const int arc_segment_count = ImMax((int)ImCeil(circle_segment_count * arc_length / (IM_PI * 2.0f)), (int)(2.0f * IM_PI / arc_length)); |
| 1213 | _PathArcToN(center, radius, a_min, a_max, arc_segment_count); |
| 1214 | } |
| 1215 | } |
| 1216 | |
| 1217 | ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t) |
| 1218 | { |
no test coverage detected