mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
Gizmos: arc_2d
utility helpers (#14932)
# Objective Since https://github.com/bevyengine/bevy/pull/14731 is merged, it unblocked a few utility methods for 2D arcs. In 2D the pendant to `long_arc_3d_between` and `short_arc_3d_between` are missing. Since `arc_2d` can be a bit hard to use, this PR is trying to plug some holes in the `arcs` API. ## Solution Implement - `long_arc_2d_between(center, from, tp, color)` - `short_arc_2d_between(center, from, tp, color)` ## Testing - There are new doc tests - The `2d_gizmos` example has been extended a bit to include a few more arcs which can easily be checked with respect to the grid --- ## Showcase ![image](https://github.com/user-attachments/assets/b90ad8b1-86c2-4304-a481-4f9a5246c457) Code related to the screenshot (from outer = first line to inner = last line) ```rust my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED); my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED); my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED); ```
This commit is contained in:
parent
419359b9a7
commit
210c79c9f9
2 changed files with 126 additions and 2 deletions
|
@ -6,7 +6,7 @@
|
|||
use crate::circles::DEFAULT_CIRCLE_RESOLUTION;
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use bevy_color::Color;
|
||||
use bevy_math::{Isometry2d, Isometry3d, Quat, Vec2, Vec3};
|
||||
use bevy_math::{Isometry2d, Isometry3d, Quat, Rot2, Vec2, Vec3};
|
||||
use std::f32::consts::{FRAC_PI_2, TAU};
|
||||
|
||||
// === 2D ===
|
||||
|
@ -321,6 +321,128 @@ where
|
|||
resolution: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws the shortest arc between two points (`from` and `to`) relative to a specified `center` point.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `center`: The center point around which the arc is drawn.
|
||||
/// - `from`: The starting point of the arc.
|
||||
/// - `to`: The ending point of the arc.
|
||||
/// - `color`: color of the arc
|
||||
///
|
||||
/// # Builder methods
|
||||
/// The resolution of the arc (i.e. the level of detail) can be adjusted with the
|
||||
/// `.resolution(...)` method.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use bevy_gizmos::prelude::*;
|
||||
/// # use bevy_math::prelude::*;
|
||||
/// # use bevy_color::palettes::css::ORANGE;
|
||||
/// fn system(mut gizmos: Gizmos) {
|
||||
/// gizmos.short_arc_2d_between(
|
||||
/// Vec2::ZERO,
|
||||
/// Vec2::X,
|
||||
/// Vec2::Y,
|
||||
/// ORANGE
|
||||
/// )
|
||||
/// .resolution(100);
|
||||
/// }
|
||||
/// # bevy_ecs::system::assert_is_system(system);
|
||||
/// ```
|
||||
///
|
||||
/// # Notes
|
||||
/// - This method assumes that the points `from` and `to` are distinct from `center`. If one of
|
||||
/// the points is coincident with `center`, nothing is rendered.
|
||||
/// - The arc is drawn as a portion of a circle with a radius equal to the distance from the
|
||||
/// `center` to `from`. If the distance from `center` to `to` is not equal to the radius, then
|
||||
/// the results will behave as if this were the case
|
||||
#[inline]
|
||||
pub fn short_arc_2d_between(
|
||||
&mut self,
|
||||
center: Vec2,
|
||||
from: Vec2,
|
||||
to: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
self.arc_2d_from_to(center, from, to, color, std::convert::identity)
|
||||
}
|
||||
|
||||
/// Draws the longest arc between two points (`from` and `to`) relative to a specified `center` point.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `center`: The center point around which the arc is drawn.
|
||||
/// - `from`: The starting point of the arc.
|
||||
/// - `to`: The ending point of the arc.
|
||||
/// - `color`: color of the arc
|
||||
///
|
||||
/// # Builder methods
|
||||
/// The resolution of the arc (i.e. the level of detail) can be adjusted with the
|
||||
/// `.resolution(...)` method.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use bevy_gizmos::prelude::*;
|
||||
/// # use bevy_math::prelude::*;
|
||||
/// # use bevy_color::palettes::css::ORANGE;
|
||||
/// fn system(mut gizmos: Gizmos) {
|
||||
/// gizmos.long_arc_2d_between(
|
||||
/// Vec2::ZERO,
|
||||
/// Vec2::X,
|
||||
/// Vec2::Y,
|
||||
/// ORANGE
|
||||
/// )
|
||||
/// .resolution(100);
|
||||
/// }
|
||||
/// # bevy_ecs::system::assert_is_system(system);
|
||||
/// ```
|
||||
///
|
||||
/// # Notes
|
||||
/// - This method assumes that the points `from` and `to` are distinct from `center`. If one of
|
||||
/// the points is coincident with `center`, nothing is rendered.
|
||||
/// - The arc is drawn as a portion of a circle with a radius equal to the distance from the
|
||||
/// `center` to `from`. If the distance from `center` to `to` is not equal to the radius, then
|
||||
/// the results will behave as if this were the case.
|
||||
#[inline]
|
||||
pub fn long_arc_2d_between(
|
||||
&mut self,
|
||||
center: Vec2,
|
||||
from: Vec2,
|
||||
to: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
self.arc_2d_from_to(center, from, to, color, |angle| angle - TAU)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn arc_2d_from_to(
|
||||
&mut self,
|
||||
center: Vec2,
|
||||
from: Vec2,
|
||||
to: Vec2,
|
||||
color: impl Into<Color>,
|
||||
angle_fn: impl Fn(f32) -> f32,
|
||||
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
// `from` and `to` can be the same here since in either case nothing gets rendered and the
|
||||
// orientation ambiguity of `up` doesn't matter
|
||||
let from_axis = (from - center).normalize_or_zero();
|
||||
let to_axis = (to - center).normalize_or_zero();
|
||||
let rotation = Vec2::Y.angle_to(from_axis);
|
||||
let arc_angle_raw = from_axis.angle_to(to_axis);
|
||||
|
||||
let arc_angle = angle_fn(arc_angle_raw);
|
||||
let radius = center.distance(from);
|
||||
|
||||
Arc2dBuilder {
|
||||
gizmos: self,
|
||||
isometry: Isometry2d::new(center, Rot2::radians(rotation)),
|
||||
arc_angle,
|
||||
radius,
|
||||
color: color.into(),
|
||||
resolution: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::arc_2d`].
|
||||
|
|
|
@ -97,7 +97,9 @@ fn draw_example_collection(
|
|||
310.,
|
||||
ORANGE_RED,
|
||||
);
|
||||
my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 75.0, ORANGE_RED);
|
||||
my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
|
||||
my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
|
||||
my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
|
||||
|
||||
gizmos.arrow_2d(
|
||||
Vec2::ZERO,
|
||||
|
|
Loading…
Reference in a new issue