Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added arc_2d function for gizmos #8448

Merged
merged 14 commits into from
Apr 21, 2023
92 changes: 92 additions & 0 deletions crates/bevy_gizmos/src/gizmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,45 @@ impl<'s> Gizmos<'s> {
}
}

/// Draw an arc, which is a part of the circumference of a circle.
///
/// # Example
/// ```
/// # use bevy_gizmos::prelude::*;
/// # use bevy_render::prelude::*;
/// # use bevy_math::prelude::*;
/// # use std::f32::consts::PI;
/// fn system(mut gizmos: Gizmos) {
/// gizmos.arc_2d(Vec2::ZERO, 0., PI / 4., 1., Color::GREEN);
///
/// // Arcs have 32 line-segments by default.
/// // You may want to increase this for larger arcs.
/// gizmos
/// .arc_2d(Vec2::ZERO, 0., PI / 4., 5., Color::RED)
/// .segments(64);
/// }
/// # bevy_ecs::system::assert_is_system(system);
/// ```
#[inline]
pub fn arc_2d(
&mut self,
position: Vec2,
center_angle: f32,
Kjolnyr marked this conversation as resolved.
Show resolved Hide resolved
arc_angle: f32,
Kjolnyr marked this conversation as resolved.
Show resolved Hide resolved
radius: f32,
color: Color,
) -> Arc2dBuilder<'_, 's> {
Arc2dBuilder {
gizmos: self,
position,
center_angle,
arc_angle,
radius,
color,
segments: None,
}
}

/// Draw a wireframe rectangle.
///
/// # Example
Expand Down Expand Up @@ -589,6 +628,59 @@ impl Drop for Circle2dBuilder<'_, '_> {
}
}

/// A builder returned by [`Gizmos::arc_2d`].
/// `center_angle` is the angle where the arc will be centered. `0.0`
/// `arc_angle` is defining the amount of the underlying circle
/// being drawn. With the `radius`, it will define the length of the arc.
pub struct Arc2dBuilder<'a, 's> {
gizmos: &'a mut Gizmos<'s>,
position: Vec2,
center_angle: f32,
arc_angle: f32,
radius: f32,
color: Color,
segments: Option<usize>,
}

impl Arc2dBuilder<'_, '_> {
/// Set the number of line-segements for this arc.
pub fn segments(mut self, segments: usize) -> Self {
Kjolnyr marked this conversation as resolved.
Show resolved Hide resolved
self.segments = Some(segments);
self
}
}

impl Drop for Arc2dBuilder<'_, '_> {
fn drop(&mut self) {
let segments = match self.segments {
Some(segments) => segments,

Kjolnyr marked this conversation as resolved.
Show resolved Hide resolved
// Do a linear interpolation between 1 and `DEFAULT_CIRCLE_SEGMENTS`
// using the arc angle as scalar.
None => (1. + (self.arc_angle.abs() / TAU) * (DEFAULT_CIRCLE_SEGMENTS as f32 - 1.))
Kjolnyr marked this conversation as resolved.
Show resolved Hide resolved
.round() as usize,
Kjolnyr marked this conversation as resolved.
Show resolved Hide resolved
};

let positions = arc_inner(self.center_angle, self.arc_angle, self.radius, segments)
.map(|vec2| (vec2 + self.position));
self.gizmos.linestrip_2d(positions, self.color);
}
}

fn arc_inner(
center_angle: f32,
arc_angle: f32,
radius: f32,
segments: usize,
) -> impl Iterator<Item = Vec2> {
(0..segments + 1).map(move |i| {
let start = center_angle - arc_angle / 2.;

let angle = start + (i as f32 * (arc_angle / segments as f32));
Vec2::from(angle.sin_cos()) * radius
})
}

fn circle_inner(radius: f32, segments: usize) -> impl Iterator<Item = Vec2> {
(0..segments + 1).map(move |i| {
let angle = i as f32 * TAU / segments as f32;
Expand Down
6 changes: 6 additions & 0 deletions examples/2d/2d_gizmos.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! This example demonstrates Bevy's immediate mode drawing API intended for visual debugging.

use std::f32::consts::PI;

use bevy::prelude::*;

fn main() {
Expand Down Expand Up @@ -38,4 +40,8 @@ fn system(mut gizmos: Gizmos, time: Res<Time>) {
gizmos.circle_2d(Vec2::ZERO, 120., Color::BLACK);
// You may want to increase this for larger circles.
gizmos.circle_2d(Vec2::ZERO, 300., Color::NAVY).segments(64);

// Arcs default amount of segments is linerarly interpolated between
// 1 and 32, using the arc length as scalar.
gizmos.arc_2d(Vec2::ZERO, sin / 10., PI / 2., 350., Color::ORANGE_RED);
}
1 change: 0 additions & 1 deletion examples/wasm/assets
Kjolnyr marked this conversation as resolved.
Show resolved Hide resolved

This file was deleted.