@@ -293,6 +293,39 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
293
293
Self :: new ( manipulator_groups, true )
294
294
}
295
295
296
+ /// Constructs an arc by a `radius`, `angle_start` and `angle_size`. Angles must be in radians.
297
+ pub fn new_arc ( radius : f64 , angle_start : f64 , angle_size : f64 ) -> Self {
298
+ let center = DVec2 :: new ( 0. , 0. ) ;
299
+ let segments = ( angle_size. abs ( ) / ( std:: f64:: consts:: PI / 4. ) ) . ceil ( ) as usize ;
300
+ let step = angle_size / segments as f64 ;
301
+ let half_step = step / 2. ;
302
+ let factor = 4. / 3. * half_step. sin ( ) / ( 1. + half_step. cos ( ) ) ;
303
+
304
+ let mut manipulator_groups = Vec :: with_capacity ( segments) ;
305
+ let mut prev_in_handle = None ;
306
+ let mut prev_end = DVec2 :: new ( 0. , 0. ) ;
307
+
308
+ for i in 0 ..segments {
309
+ let start_angle = angle_start + step * i as f64 ;
310
+ let end_angle = start_angle + step;
311
+ let start_vec = DVec2 :: from_angle ( start_angle) ;
312
+ let end_vec = DVec2 :: from_angle ( end_angle) ;
313
+
314
+ let start = center + radius * start_vec;
315
+ let end = center + radius * end_vec;
316
+
317
+ let handle_start = start + start_vec. perp ( ) * radius * factor;
318
+ let handle_end = end - end_vec. perp ( ) * radius * factor;
319
+
320
+ manipulator_groups. push ( ManipulatorGroup :: new ( start, prev_in_handle, Some ( handle_start) ) ) ;
321
+ prev_in_handle = Some ( handle_end) ;
322
+ prev_end = end;
323
+ }
324
+ manipulator_groups. push ( ManipulatorGroup :: new ( prev_end, prev_in_handle, None ) ) ;
325
+
326
+ Self :: new ( manipulator_groups, false )
327
+ }
328
+
296
329
/// Constructs a regular polygon (ngon). Based on `sides` and `radius`, which is the distance from the center to any vertex.
297
330
pub fn new_regular_polygon ( center : DVec2 , sides : u64 , radius : f64 ) -> Self {
298
331
let angle_increment = std:: f64:: consts:: TAU / ( sides as f64 ) ;
0 commit comments