Skip to content

Commit ddefc24

Browse files
Kjolnyrkjolnyralice-i-ceciletim-blackbird
authored
Added arc_2d function for gizmos (bevyengine#8448)
# Objective Added the possibility to draw arcs in 2d via gizmos ## Solution - Added `arc_2d` function to `Gizmos` - Added `arc_inner` function - Added `Arc2dBuilder<'a, 's>` - Updated `2d_gizmos.rs` example to draw an arc --------- Co-authored-by: kjolnyr <[email protected]> Co-authored-by: Alice Cecile <[email protected]> Co-authored-by: ira <[email protected]>
1 parent 0cf3000 commit ddefc24

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

crates/bevy_gizmos/src/gizmos.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,51 @@ impl<'s> Gizmos<'s> {
459459
}
460460
}
461461

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+
462507
/// Draw a wireframe rectangle.
463508
///
464509
/// # Example
@@ -589,6 +634,54 @@ impl Drop for Circle2dBuilder<'_, '_> {
589634
}
590635
}
591636

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+
592685
fn circle_inner(radius: f32, segments: usize) -> impl Iterator<Item = Vec2> {
593686
(0..segments + 1).map(move |i| {
594687
let angle = i as f32 * TAU / segments as f32;

examples/2d/2d_gizmos.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! This example demonstrates Bevy's immediate mode drawing API intended for visual debugging.
22
3+
use std::f32::consts::PI;
4+
35
use bevy::prelude::*;
46

57
fn main() {
@@ -38,4 +40,8 @@ fn system(mut gizmos: Gizmos, time: Res<Time>) {
3840
gizmos.circle_2d(Vec2::ZERO, 120., Color::BLACK);
3941
// You may want to increase this for larger circles.
4042
gizmos.circle_2d(Vec2::ZERO, 300., Color::NAVY).segments(64);
43+
44+
// Arcs default amount of segments is linerarly interpolated between
45+
// 1 and 32, using the arc length as scalar.
46+
gizmos.arc_2d(Vec2::ZERO, sin / 10., PI / 2., 350., Color::ORANGE_RED);
4147
}

0 commit comments

Comments
 (0)