@@ -459,6 +459,51 @@ impl<'s> Gizmos<'s> {
459
459
}
460
460
}
461
461
462
+ /// Draw an arc, which is a part of the circumference of a circle.
463
+ ///
464
+ /// # Arguments
465
+ /// - `position` sets the center of this circle.
466
+ /// - `radius` controls the distance from `position` to this arc, and thus its curvature.
467
+ /// - `direction_angle` sets the angle in radians between `position` and the midpoint of the arc.
468
+ /// -`arc_angle` sets the length of this arc, in radians.
469
+ ///
470
+ /// # Example
471
+ /// ```
472
+ /// # use bevy_gizmos::prelude::*;
473
+ /// # use bevy_render::prelude::*;
474
+ /// # use bevy_math::prelude::*;
475
+ /// # use std::f32::consts::PI;
476
+ /// fn system(mut gizmos: Gizmos) {
477
+ /// gizmos.arc_2d(Vec2::ZERO, 0., PI / 4., 1., Color::GREEN);
478
+ ///
479
+ /// // Arcs have 32 line-segments by default.
480
+ /// // You may want to increase this for larger arcs.
481
+ /// gizmos
482
+ /// .arc_2d(Vec2::ZERO, 0., PI / 4., 5., Color::RED)
483
+ /// .segments(64);
484
+ /// }
485
+ /// # bevy_ecs::system::assert_is_system(system);
486
+ /// ```
487
+ #[ inline]
488
+ pub fn arc_2d (
489
+ & mut self ,
490
+ position : Vec2 ,
491
+ direction_angle : f32 ,
492
+ arc_angle : f32 ,
493
+ radius : f32 ,
494
+ color : Color ,
495
+ ) -> Arc2dBuilder < ' _ , ' s > {
496
+ Arc2dBuilder {
497
+ gizmos : self ,
498
+ position,
499
+ direction_angle,
500
+ arc_angle,
501
+ radius,
502
+ color,
503
+ segments : None ,
504
+ }
505
+ }
506
+
462
507
/// Draw a wireframe rectangle.
463
508
///
464
509
/// # Example
@@ -589,6 +634,54 @@ impl Drop for Circle2dBuilder<'_, '_> {
589
634
}
590
635
}
591
636
637
+ /// A builder returned by [`Gizmos::arc_2d`].
638
+ pub struct Arc2dBuilder < ' a , ' s > {
639
+ gizmos : & ' a mut Gizmos < ' s > ,
640
+ position : Vec2 ,
641
+ direction_angle : f32 ,
642
+ arc_angle : f32 ,
643
+ radius : f32 ,
644
+ color : Color ,
645
+ segments : Option < usize > ,
646
+ }
647
+
648
+ impl Arc2dBuilder < ' _ , ' _ > {
649
+ /// Set the number of line-segements for this arc.
650
+ pub fn segments ( mut self , segments : usize ) -> Self {
651
+ self . segments = Some ( segments) ;
652
+ self
653
+ }
654
+ }
655
+
656
+ impl Drop for Arc2dBuilder < ' _ , ' _ > {
657
+ fn drop ( & mut self ) {
658
+ let segments = match self . segments {
659
+ Some ( segments) => segments,
660
+ // Do a linear interpolation between 1 and `DEFAULT_CIRCLE_SEGMENTS`
661
+ // using the arc angle as scalar.
662
+ None => ( ( self . arc_angle . abs ( ) / TAU ) * DEFAULT_CIRCLE_SEGMENTS as f32 ) . ceil ( ) as usize ,
663
+ } ;
664
+
665
+ let positions = arc_inner ( self . direction_angle , self . arc_angle , self . radius , segments)
666
+ . map ( |vec2| ( vec2 + self . position ) ) ;
667
+ self . gizmos . linestrip_2d ( positions, self . color ) ;
668
+ }
669
+ }
670
+
671
+ fn arc_inner (
672
+ direction_angle : f32 ,
673
+ arc_angle : f32 ,
674
+ radius : f32 ,
675
+ segments : usize ,
676
+ ) -> impl Iterator < Item = Vec2 > {
677
+ ( 0 ..segments + 1 ) . map ( move |i| {
678
+ let start = direction_angle - arc_angle / 2. ;
679
+
680
+ let angle = start + ( i as f32 * ( arc_angle / segments as f32 ) ) ;
681
+ Vec2 :: from ( angle. sin_cos ( ) ) * radius
682
+ } )
683
+ }
684
+
592
685
fn circle_inner ( radius : f32 , segments : usize ) -> impl Iterator < Item = Vec2 > {
593
686
( 0 ..segments + 1 ) . map ( move |i| {
594
687
let angle = i as f32 * TAU / segments as f32 ;
0 commit comments