Rename Rotation2d to Rot2 (#13694)

# Objective

- `Rotation2d` is a very long name for a commonly used type.

## Solution

- Rename it to `Rot2` to match `glam`'s naming convention (e.g. `Vec2`)

I ran a poll, and `Rot2` was the favorite of the candidate names.

This is not actually a breaking change, since `Rotation2d` has not been
shipped yet.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
This commit is contained in:
Alice Cecile 2024-06-05 17:51:13 -04:00 committed by GitHub
parent 2eb9d5cc38
commit 2165f2218f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 145 additions and 222 deletions

View file

@ -8,7 +8,7 @@ use bevy_ecs::{
system::{Deferred, ReadOnlySystemParam, Res, Resource, SystemBuffer, SystemMeta, SystemParam}, system::{Deferred, ReadOnlySystemParam, Res, Resource, SystemBuffer, SystemMeta, SystemParam},
world::{unsafe_world_cell::UnsafeWorldCell, World}, world::{unsafe_world_cell::UnsafeWorldCell, World},
}; };
use bevy_math::{Quat, Rotation2d, Vec2, Vec3}; use bevy_math::{Quat, Rot2, Vec2, Vec3};
use bevy_transform::TransformPoint; use bevy_transform::TransformPoint;
use bevy_utils::default; use bevy_utils::default;
@ -707,14 +707,14 @@ where
pub fn rect_2d( pub fn rect_2d(
&mut self, &mut self,
position: Vec2, position: Vec2,
rotation: impl Into<Rotation2d>, rotation: impl Into<Rot2>,
size: Vec2, size: Vec2,
color: impl Into<Color>, color: impl Into<Color>,
) { ) {
if !self.enabled { if !self.enabled {
return; return;
} }
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let [tl, tr, br, bl] = rect_inner(size).map(|vec2| position + rotation * vec2); let [tl, tr, br, bl] = rect_inner(size).map(|vec2| position + rotation * vec2);
self.linestrip_2d([tl, tr, br, bl, tl], color); self.linestrip_2d([tl, tr, br, bl, tl], color);
} }

View file

@ -1,7 +1,7 @@
mod primitive_impls; mod primitive_impls;
use super::{BoundingVolume, IntersectsVolume}; use super::{BoundingVolume, IntersectsVolume};
use crate::prelude::{Mat2, Rotation2d, Vec2}; use crate::prelude::{Mat2, Rot2, Vec2};
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
@ -22,11 +22,10 @@ fn point_cloud_2d_center(points: &[Vec2]) -> Vec2 {
pub trait Bounded2d { pub trait Bounded2d {
/// Get an axis-aligned bounding box for the shape with the given translation and rotation. /// Get an axis-aligned bounding box for the shape with the given translation and rotation.
/// The rotation is in radians, counterclockwise, with 0 meaning no rotation. /// The rotation is in radians, counterclockwise, with 0 meaning no rotation.
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d; fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d;
/// Get a bounding circle for the shape /// Get a bounding circle for the shape
/// The rotation is in radians, counterclockwise, with 0 meaning no rotation. /// The rotation is in radians, counterclockwise, with 0 meaning no rotation.
fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rotation2d>) fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle;
-> BoundingCircle;
} }
/// A 2D axis-aligned bounding box, or bounding rectangle /// A 2D axis-aligned bounding box, or bounding rectangle
@ -60,11 +59,11 @@ impl Aabb2d {
#[inline(always)] #[inline(always)]
pub fn from_point_cloud( pub fn from_point_cloud(
translation: Vec2, translation: Vec2,
rotation: impl Into<Rotation2d>, rotation: impl Into<Rot2>,
points: &[Vec2], points: &[Vec2],
) -> Aabb2d { ) -> Aabb2d {
// Transform all points by rotation // Transform all points by rotation
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let mut iter = points.iter().map(|point| rotation * *point); let mut iter = points.iter().map(|point| rotation * *point);
let first = iter let first = iter
@ -101,7 +100,7 @@ impl Aabb2d {
impl BoundingVolume for Aabb2d { impl BoundingVolume for Aabb2d {
type Translation = Vec2; type Translation = Vec2;
type Rotation = Rotation2d; type Rotation = Rot2;
type HalfSize = Vec2; type HalfSize = Vec2;
#[inline(always)] #[inline(always)]
@ -232,7 +231,7 @@ impl BoundingVolume for Aabb2d {
/// and consider storing the original AABB and rotating that every time instead. /// and consider storing the original AABB and rotating that every time instead.
#[inline(always)] #[inline(always)]
fn rotate_by(&mut self, rotation: impl Into<Self::Rotation>) { fn rotate_by(&mut self, rotation: impl Into<Self::Rotation>) {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let abs_rot_mat = Mat2::from_cols( let abs_rot_mat = Mat2::from_cols(
Vec2::new(rotation.cos, rotation.sin), Vec2::new(rotation.cos, rotation.sin),
Vec2::new(rotation.sin, rotation.cos), Vec2::new(rotation.sin, rotation.cos),
@ -479,10 +478,10 @@ impl BoundingCircle {
#[inline(always)] #[inline(always)]
pub fn from_point_cloud( pub fn from_point_cloud(
translation: Vec2, translation: Vec2,
rotation: impl Into<Rotation2d>, rotation: impl Into<Rot2>,
points: &[Vec2], points: &[Vec2],
) -> BoundingCircle { ) -> BoundingCircle {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let center = point_cloud_2d_center(points); let center = point_cloud_2d_center(points);
let mut radius_squared = 0.0; let mut radius_squared = 0.0;
@ -524,7 +523,7 @@ impl BoundingCircle {
impl BoundingVolume for BoundingCircle { impl BoundingVolume for BoundingCircle {
type Translation = Vec2; type Translation = Vec2;
type Rotation = Rotation2d; type Rotation = Rot2;
type HalfSize = f32; type HalfSize = f32;
#[inline(always)] #[inline(always)]
@ -594,7 +593,7 @@ impl BoundingVolume for BoundingCircle {
#[inline(always)] #[inline(always)]
fn rotate_by(&mut self, rotation: impl Into<Self::Rotation>) { fn rotate_by(&mut self, rotation: impl Into<Self::Rotation>) {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
self.center = rotation * self.center; self.center = rotation * self.center;
} }
} }

View file

@ -6,7 +6,7 @@ use crate::{
Ellipse, Line2d, Plane2d, Polygon, Polyline2d, Rectangle, RegularPolygon, Rhombus, Ellipse, Line2d, Plane2d, Polygon, Polyline2d, Rectangle, RegularPolygon, Rhombus,
Segment2d, Triangle2d, Segment2d, Triangle2d,
}, },
Dir2, Mat2, Rotation2d, Vec2, Dir2, Mat2, Rot2, Vec2,
}; };
use std::f32::consts::{FRAC_PI_2, PI, TAU}; use std::f32::consts::{FRAC_PI_2, PI, TAU};
@ -15,15 +15,11 @@ use smallvec::SmallVec;
use super::{Aabb2d, Bounded2d, BoundingCircle}; use super::{Aabb2d, Bounded2d, BoundingCircle};
impl Bounded2d for Circle { impl Bounded2d for Circle {
fn aabb_2d(&self, translation: Vec2, _rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> Aabb2d {
Aabb2d::new(translation, Vec2::splat(self.radius)) Aabb2d::new(translation, Vec2::splat(self.radius))
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, self.radius) BoundingCircle::new(translation, self.radius)
} }
} }
@ -31,7 +27,7 @@ impl Bounded2d for Circle {
// Compute the axis-aligned bounding points of a rotated arc, used for computing the AABB of arcs and derived shapes. // Compute the axis-aligned bounding points of a rotated arc, used for computing the AABB of arcs and derived shapes.
// The return type has room for 7 points so that the CircularSector code can add an additional point. // The return type has room for 7 points so that the CircularSector code can add an additional point.
#[inline] #[inline]
fn arc_bounding_points(arc: Arc2d, rotation: impl Into<Rotation2d>) -> SmallVec<[Vec2; 7]> { fn arc_bounding_points(arc: Arc2d, rotation: impl Into<Rot2>) -> SmallVec<[Vec2; 7]> {
// Otherwise, the extreme points will always be either the endpoints or the axis-aligned extrema of the arc's circle. // Otherwise, the extreme points will always be either the endpoints or the axis-aligned extrema of the arc's circle.
// We need to compute which axis-aligned extrema are actually contained within the rotated arc. // We need to compute which axis-aligned extrema are actually contained within the rotated arc.
let mut bounds = SmallVec::<[Vec2; 7]>::new(); let mut bounds = SmallVec::<[Vec2; 7]>::new();
@ -61,7 +57,7 @@ fn arc_bounding_points(arc: Arc2d, rotation: impl Into<Rotation2d>) -> SmallVec<
} }
impl Bounded2d for Arc2d { impl Bounded2d for Arc2d {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
// If our arc covers more than a circle, just return the bounding box of the circle. // If our arc covers more than a circle, just return the bounding box of the circle.
if self.half_angle >= PI { if self.half_angle >= PI {
return Circle::new(self.radius).aabb_2d(translation, rotation); return Circle::new(self.radius).aabb_2d(translation, rotation);
@ -70,11 +66,7 @@ impl Bounded2d for Arc2d {
Aabb2d::from_point_cloud(translation, 0.0, &arc_bounding_points(*self, rotation)) Aabb2d::from_point_cloud(translation, 0.0, &arc_bounding_points(*self, rotation))
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
// There are two possibilities for the bounding circle. // There are two possibilities for the bounding circle.
if self.is_major() { if self.is_major() {
// If the arc is major, then the widest distance between two points is a diameter of the arc's circle; // If the arc is major, then the widest distance between two points is a diameter of the arc's circle;
@ -90,7 +82,7 @@ impl Bounded2d for Arc2d {
} }
impl Bounded2d for CircularSector { impl Bounded2d for CircularSector {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
// If our sector covers more than a circle, just return the bounding box of the circle. // If our sector covers more than a circle, just return the bounding box of the circle.
if self.half_angle() >= PI { if self.half_angle() >= PI {
return Circle::new(self.radius()).aabb_2d(translation, rotation); return Circle::new(self.radius()).aabb_2d(translation, rotation);
@ -103,11 +95,7 @@ impl Bounded2d for CircularSector {
Aabb2d::from_point_cloud(translation, 0.0, &bounds) Aabb2d::from_point_cloud(translation, 0.0, &bounds)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
if self.arc.is_major() { if self.arc.is_major() {
// If the arc is major, that is, greater than a semicircle, // If the arc is major, that is, greater than a semicircle,
// then bounding circle is just the circle defining the sector. // then bounding circle is just the circle defining the sector.
@ -129,22 +117,18 @@ impl Bounded2d for CircularSector {
} }
impl Bounded2d for CircularSegment { impl Bounded2d for CircularSegment {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
self.arc.aabb_2d(translation, rotation) self.arc.aabb_2d(translation, rotation)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
self.arc.bounding_circle(translation, rotation) self.arc.bounding_circle(translation, rotation)
} }
} }
impl Bounded2d for Ellipse { impl Bounded2d for Ellipse {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
// V = (hh * cos(beta), hh * sin(beta)) // V = (hh * cos(beta), hh * sin(beta))
// #####*##### // #####*#####
@ -174,17 +158,13 @@ impl Bounded2d for Ellipse {
Aabb2d::new(translation, half_size) Aabb2d::new(translation, half_size)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, self.semi_major()) BoundingCircle::new(translation, self.semi_major())
} }
} }
impl Bounded2d for Rhombus { impl Bounded2d for Rhombus {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation_mat = rotation.into(); let rotation_mat = rotation.into();
let [rotated_x_half_diagonal, rotated_y_half_diagonal] = [ let [rotated_x_half_diagonal, rotated_y_half_diagonal] = [
@ -201,18 +181,14 @@ impl Bounded2d for Rhombus {
} }
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, self.circumradius()) BoundingCircle::new(translation, self.circumradius())
} }
} }
impl Bounded2d for Plane2d { impl Bounded2d for Plane2d {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let normal = rotation * *self.normal; let normal = rotation * *self.normal;
let facing_x = normal == Vec2::X || normal == Vec2::NEG_X; let facing_x = normal == Vec2::X || normal == Vec2::NEG_X;
let facing_y = normal == Vec2::Y || normal == Vec2::NEG_Y; let facing_y = normal == Vec2::Y || normal == Vec2::NEG_Y;
@ -226,18 +202,14 @@ impl Bounded2d for Plane2d {
Aabb2d::new(translation, half_size) Aabb2d::new(translation, half_size)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, f32::MAX / 2.0) BoundingCircle::new(translation, f32::MAX / 2.0)
} }
} }
impl Bounded2d for Line2d { impl Bounded2d for Line2d {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let direction = rotation * *self.direction; let direction = rotation * *self.direction;
// Dividing `f32::MAX` by 2.0 is helpful so that we can do operations // Dividing `f32::MAX` by 2.0 is helpful so that we can do operations
@ -250,65 +222,49 @@ impl Bounded2d for Line2d {
Aabb2d::new(translation, half_size) Aabb2d::new(translation, half_size)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, f32::MAX / 2.0) BoundingCircle::new(translation, f32::MAX / 2.0)
} }
} }
impl Bounded2d for Segment2d { impl Bounded2d for Segment2d {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
// Rotate the segment by `rotation` // Rotate the segment by `rotation`
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let direction = rotation * *self.direction; let direction = rotation * *self.direction;
let half_size = (self.half_length * direction).abs(); let half_size = (self.half_length * direction).abs();
Aabb2d::new(translation, half_size) Aabb2d::new(translation, half_size)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, self.half_length) BoundingCircle::new(translation, self.half_length)
} }
} }
impl<const N: usize> Bounded2d for Polyline2d<N> { impl<const N: usize> Bounded2d for Polyline2d<N> {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
Aabb2d::from_point_cloud(translation, rotation, &self.vertices) Aabb2d::from_point_cloud(translation, rotation, &self.vertices)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::from_point_cloud(translation, rotation, &self.vertices) BoundingCircle::from_point_cloud(translation, rotation, &self.vertices)
} }
} }
impl Bounded2d for BoxedPolyline2d { impl Bounded2d for BoxedPolyline2d {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
Aabb2d::from_point_cloud(translation, rotation, &self.vertices) Aabb2d::from_point_cloud(translation, rotation, &self.vertices)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::from_point_cloud(translation, rotation, &self.vertices) BoundingCircle::from_point_cloud(translation, rotation, &self.vertices)
} }
} }
impl Bounded2d for Triangle2d { impl Bounded2d for Triangle2d {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let [a, b, c] = self.vertices.map(|vtx| rotation * vtx); let [a, b, c] = self.vertices.map(|vtx| rotation * vtx);
let min = Vec2::new(a.x.min(b.x).min(c.x), a.y.min(b.y).min(c.y)); let min = Vec2::new(a.x.min(b.x).min(c.x), a.y.min(b.y).min(c.y));
@ -320,12 +276,8 @@ impl Bounded2d for Triangle2d {
} }
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self, let rotation: Rot2 = rotation.into();
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
let rotation: Rotation2d = rotation.into();
let [a, b, c] = self.vertices; let [a, b, c] = self.vertices;
// The points of the segment opposite to the obtuse or right angle if one exists // The points of the segment opposite to the obtuse or right angle if one exists
@ -356,8 +308,8 @@ impl Bounded2d for Triangle2d {
} }
impl Bounded2d for Rectangle { impl Bounded2d for Rectangle {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
// Compute the AABB of the rotated rectangle by transforming the half-extents // Compute the AABB of the rotated rectangle by transforming the half-extents
// by an absolute rotation matrix. // by an absolute rotation matrix.
@ -368,47 +320,35 @@ impl Bounded2d for Rectangle {
Aabb2d::new(translation, half_size) Aabb2d::new(translation, half_size)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
let radius = self.half_size.length(); let radius = self.half_size.length();
BoundingCircle::new(translation, radius) BoundingCircle::new(translation, radius)
} }
} }
impl<const N: usize> Bounded2d for Polygon<N> { impl<const N: usize> Bounded2d for Polygon<N> {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
Aabb2d::from_point_cloud(translation, rotation, &self.vertices) Aabb2d::from_point_cloud(translation, rotation, &self.vertices)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::from_point_cloud(translation, rotation, &self.vertices) BoundingCircle::from_point_cloud(translation, rotation, &self.vertices)
} }
} }
impl Bounded2d for BoxedPolygon { impl Bounded2d for BoxedPolygon {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
Aabb2d::from_point_cloud(translation, rotation, &self.vertices) Aabb2d::from_point_cloud(translation, rotation, &self.vertices)
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::from_point_cloud(translation, rotation, &self.vertices) BoundingCircle::from_point_cloud(translation, rotation, &self.vertices)
} }
} }
impl Bounded2d for RegularPolygon { impl Bounded2d for RegularPolygon {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
let mut min = Vec2::ZERO; let mut min = Vec2::ZERO;
let mut max = Vec2::ZERO; let mut max = Vec2::ZERO;
@ -424,18 +364,14 @@ impl Bounded2d for RegularPolygon {
} }
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, self.circumcircle.radius) BoundingCircle::new(translation, self.circumcircle.radius)
} }
} }
impl Bounded2d for Capsule2d { impl Bounded2d for Capsule2d {
fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rotation2d>) -> Aabb2d { fn aabb_2d(&self, translation: Vec2, rotation: impl Into<Rot2>) -> Aabb2d {
let rotation: Rotation2d = rotation.into(); let rotation: Rot2 = rotation.into();
// Get the line segment between the hemicircles of the rotated capsule // Get the line segment between the hemicircles of the rotated capsule
let segment = Segment2d { let segment = Segment2d {
@ -455,11 +391,7 @@ impl Bounded2d for Capsule2d {
} }
} }
fn bounding_circle( fn bounding_circle(&self, translation: Vec2, _rotation: impl Into<Rot2>) -> BoundingCircle {
&self,
translation: Vec2,
_rotation: impl Into<Rotation2d>,
) -> BoundingCircle {
BoundingCircle::new(translation, self.radius + self.half_length) BoundingCircle::new(translation, self.radius + self.half_length)
} }
} }

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
primitives::{Primitive2d, Primitive3d}, primitives::{Primitive2d, Primitive3d},
Quat, Rotation2d, Vec2, Vec3, Vec3A, Quat, Rot2, Vec2, Vec3, Vec3A,
}; };
use core::f32::consts::FRAC_1_SQRT_2; use core::f32::consts::FRAC_1_SQRT_2;
@ -200,47 +200,47 @@ impl Dir2 {
#[inline] #[inline]
pub fn slerp(self, rhs: Self, s: f32) -> Self { pub fn slerp(self, rhs: Self, s: f32) -> Self {
let angle = self.angle_between(rhs.0); let angle = self.angle_between(rhs.0);
Rotation2d::radians(angle * s) * self Rot2::radians(angle * s) * self
} }
/// Get the rotation that rotates this direction to `other`. /// Get the rotation that rotates this direction to `other`.
#[inline] #[inline]
pub fn rotation_to(self, other: Self) -> Rotation2d { pub fn rotation_to(self, other: Self) -> Rot2 {
// Rotate `self` to X-axis, then X-axis to `other`: // Rotate `self` to X-axis, then X-axis to `other`:
other.rotation_from_x() * self.rotation_to_x() other.rotation_from_x() * self.rotation_to_x()
} }
/// Get the rotation that rotates `other` to this direction. /// Get the rotation that rotates `other` to this direction.
#[inline] #[inline]
pub fn rotation_from(self, other: Self) -> Rotation2d { pub fn rotation_from(self, other: Self) -> Rot2 {
other.rotation_to(self) other.rotation_to(self)
} }
/// Get the rotation that rotates the X-axis to this direction. /// Get the rotation that rotates the X-axis to this direction.
#[inline] #[inline]
pub fn rotation_from_x(self) -> Rotation2d { pub fn rotation_from_x(self) -> Rot2 {
Rotation2d::from_sin_cos(self.0.y, self.0.x) Rot2::from_sin_cos(self.0.y, self.0.x)
} }
/// Get the rotation that rotates this direction to the X-axis. /// Get the rotation that rotates this direction to the X-axis.
#[inline] #[inline]
pub fn rotation_to_x(self) -> Rotation2d { pub fn rotation_to_x(self) -> Rot2 {
// (This is cheap, it just negates one component.) // (This is cheap, it just negates one component.)
self.rotation_from_x().inverse() self.rotation_from_x().inverse()
} }
/// Get the rotation that rotates this direction to the Y-axis. /// Get the rotation that rotates this direction to the Y-axis.
#[inline] #[inline]
pub fn rotation_from_y(self) -> Rotation2d { pub fn rotation_from_y(self) -> Rot2 {
// `x <- y`, `y <- -x` correspond to rotating clockwise by pi/2; // `x <- y`, `y <- -x` correspond to rotating clockwise by pi/2;
// this transforms the Y-axis into the X-axis, maintaining the relative position // this transforms the Y-axis into the X-axis, maintaining the relative position
// of our direction. Then we just use the same technique as `rotation_from_x`. // of our direction. Then we just use the same technique as `rotation_from_x`.
Rotation2d::from_sin_cos(-self.0.x, self.0.y) Rot2::from_sin_cos(-self.0.x, self.0.y)
} }
/// Get the rotation that rotates the Y-axis to this direction. /// Get the rotation that rotates the Y-axis to this direction.
#[inline] #[inline]
pub fn rotation_to_y(self) -> Rotation2d { pub fn rotation_to_y(self) -> Rot2 {
self.rotation_from_y().inverse() self.rotation_from_y().inverse()
} }
} }
@ -287,10 +287,10 @@ impl std::ops::Mul<Dir2> for f32 {
} }
} }
impl std::ops::Mul<Dir2> for Rotation2d { impl std::ops::Mul<Dir2> for Rot2 {
type Output = Dir2; type Output = Dir2;
/// Rotates the [`Dir2`] using a [`Rotation2d`]. /// Rotates the [`Dir2`] using a [`Rot2`].
fn mul(self, direction: Dir2) -> Self::Output { fn mul(self, direction: Dir2) -> Self::Output {
let rotated = self * *direction; let rotated = self * *direction;
@ -807,21 +807,12 @@ mod tests {
#[test] #[test]
fn dir2_to_rotation2d() { fn dir2_to_rotation2d() {
assert_relative_eq!( assert_relative_eq!(Dir2::EAST.rotation_to(Dir2::NORTH_EAST), Rot2::FRAC_PI_4);
Dir2::EAST.rotation_to(Dir2::NORTH_EAST), assert_relative_eq!(Dir2::NORTH.rotation_from(Dir2::NORTH_EAST), Rot2::FRAC_PI_4);
Rotation2d::FRAC_PI_4 assert_relative_eq!(Dir2::SOUTH.rotation_to_x(), Rot2::FRAC_PI_2);
); assert_relative_eq!(Dir2::SOUTH.rotation_to_y(), Rot2::PI);
assert_relative_eq!( assert_relative_eq!(Dir2::NORTH_WEST.rotation_from_x(), Rot2::degrees(135.0));
Dir2::NORTH.rotation_from(Dir2::NORTH_EAST), assert_relative_eq!(Dir2::NORTH_WEST.rotation_from_y(), Rot2::FRAC_PI_4);
Rotation2d::FRAC_PI_4
);
assert_relative_eq!(Dir2::SOUTH.rotation_to_x(), Rotation2d::FRAC_PI_2);
assert_relative_eq!(Dir2::SOUTH.rotation_to_y(), Rotation2d::PI);
assert_relative_eq!(
Dir2::NORTH_WEST.rotation_from_x(),
Rotation2d::degrees(135.0)
);
assert_relative_eq!(Dir2::NORTH_WEST.rotation_from_y(), Rotation2d::FRAC_PI_4);
} }
#[test] #[test]

View file

@ -34,7 +34,7 @@ pub use direction::*;
pub use float_ord::*; pub use float_ord::*;
pub use ray::{Ray2d, Ray3d}; pub use ray::{Ray2d, Ray3d};
pub use rects::*; pub use rects::*;
pub use rotation2d::Rotation2d; pub use rotation2d::Rot2;
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub use sampling::{FromRng, ShapeSample}; pub use sampling::{FromRng, ShapeSample};
@ -53,7 +53,7 @@ pub mod prelude {
direction::{Dir2, Dir3, Dir3A}, direction::{Dir2, Dir3, Dir3A},
primitives::*, primitives::*,
BVec2, BVec3, BVec4, EulerRot, FloatExt, IRect, IVec2, IVec3, IVec4, Mat2, Mat3, Mat4, BVec2, BVec3, BVec4, EulerRot, FloatExt, IRect, IVec2, IVec3, IVec4, Mat2, Mat3, Mat4,
Quat, Ray2d, Ray3d, Rect, Rotation2d, URect, UVec2, UVec3, UVec4, Vec2, Vec2Swizzles, Vec3, Quat, Ray2d, Ray3d, Rect, Rot2, URect, UVec2, UVec3, UVec4, Vec2, Vec2Swizzles, Vec3,
Vec3Swizzles, Vec4, Vec4Swizzles, Vec3Swizzles, Vec4, Vec4Swizzles,
}; };
} }

View file

@ -13,19 +13,19 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
/// ///
/// ``` /// ```
/// # use approx::assert_relative_eq; /// # use approx::assert_relative_eq;
/// # use bevy_math::{Rotation2d, Vec2}; /// # use bevy_math::{Rot2, Vec2};
/// use std::f32::consts::PI; /// use std::f32::consts::PI;
/// ///
/// // Create rotations from radians or degrees /// // Create rotations from radians or degrees
/// let rotation1 = Rotation2d::radians(PI / 2.0); /// let rotation1 = Rot2::radians(PI / 2.0);
/// let rotation2 = Rotation2d::degrees(45.0); /// let rotation2 = Rot2::degrees(45.0);
/// ///
/// // Get the angle back as radians or degrees /// // Get the angle back as radians or degrees
/// assert_eq!(rotation1.as_degrees(), 90.0); /// assert_eq!(rotation1.as_degrees(), 90.0);
/// assert_eq!(rotation2.as_radians(), PI / 4.0); /// assert_eq!(rotation2.as_radians(), PI / 4.0);
/// ///
/// // "Add" rotations together using `*` /// // "Add" rotations together using `*`
/// assert_relative_eq!(rotation1 * rotation2, Rotation2d::degrees(135.0)); /// assert_relative_eq!(rotation1 * rotation2, Rot2::degrees(135.0));
/// ///
/// // Rotate vectors /// // Rotate vectors
/// assert_relative_eq!(rotation1 * Vec2::X, Vec2::Y); /// assert_relative_eq!(rotation1 * Vec2::X, Vec2::Y);
@ -41,7 +41,8 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
all(feature = "serialize", feature = "bevy_reflect"), all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize) reflect(Serialize, Deserialize)
)] )]
pub struct Rotation2d { #[doc(alias = "rotation", alias = "rotation2d", alias = "rotation_2d")]
pub struct Rot2 {
/// The cosine of the rotation angle in radians. /// The cosine of the rotation angle in radians.
/// ///
/// This is the real part of the unit complex number representing the rotation. /// This is the real part of the unit complex number representing the rotation.
@ -52,13 +53,13 @@ pub struct Rotation2d {
pub sin: f32, pub sin: f32,
} }
impl Default for Rotation2d { impl Default for Rot2 {
fn default() -> Self { fn default() -> Self {
Self::IDENTITY Self::IDENTITY
} }
} }
impl Rotation2d { impl Rot2 {
/// No rotation. /// No rotation.
pub const IDENTITY: Self = Self { cos: 1.0, sin: 0.0 }; pub const IDENTITY: Self = Self { cos: 1.0, sin: 0.0 };
@ -95,7 +96,7 @@ impl Rotation2d {
sin: 0.382_683_43, sin: 0.382_683_43,
}; };
/// Creates a [`Rotation2d`] from a counterclockwise angle in radians. /// Creates a [`Rot2`] from a counterclockwise angle in radians.
#[inline] #[inline]
pub fn radians(radians: f32) -> Self { pub fn radians(radians: f32) -> Self {
#[cfg(feature = "libm")] #[cfg(feature = "libm")]
@ -109,13 +110,13 @@ impl Rotation2d {
Self::from_sin_cos(sin, cos) Self::from_sin_cos(sin, cos)
} }
/// Creates a [`Rotation2d`] from a counterclockwise angle in degrees. /// Creates a [`Rot2`] from a counterclockwise angle in degrees.
#[inline] #[inline]
pub fn degrees(degrees: f32) -> Self { pub fn degrees(degrees: f32) -> Self {
Self::radians(degrees.to_radians()) Self::radians(degrees.to_radians())
} }
/// Creates a [`Rotation2d`] from the sine and cosine of an angle in radians. /// Creates a [`Rot2`] from the sine and cosine of an angle in radians.
/// ///
/// The rotation is only valid if `sin * sin + cos * cos == 1.0`. /// The rotation is only valid if `sin * sin + cos * cos == 1.0`.
/// ///
@ -170,7 +171,7 @@ impl Rotation2d {
/// Computes the squared length or norm of the complex number used to represent the rotation. /// Computes the squared length or norm of the complex number used to represent the rotation.
/// ///
/// This is generally faster than [`Rotation2d::length()`], as it avoids a square /// This is generally faster than [`Rot2::length()`], as it avoids a square
/// root operation. /// root operation.
/// ///
/// The length is typically expected to be `1.0`. Unexpectedly denormalized rotations /// The length is typically expected to be `1.0`. Unexpectedly denormalized rotations
@ -195,7 +196,7 @@ impl Rotation2d {
/// `None` will be returned if the sine and cosine of `self` are both zero (or very close to zero), /// `None` will be returned if the sine and cosine of `self` are both zero (or very close to zero),
/// or if either of them is NaN or infinite. /// or if either of them is NaN or infinite.
/// ///
/// Note that [`Rotation2d`] should typically already be normalized by design. /// Note that [`Rot2`] should typically already be normalized by design.
/// Manual normalization is only needed when successive operations result in /// Manual normalization is only needed when successive operations result in
/// accumulated floating point error, or if the rotation was constructed /// accumulated floating point error, or if the rotation was constructed
/// with invalid values. /// with invalid values.
@ -211,7 +212,7 @@ impl Rotation2d {
/// Returns `self` with a length of `1.0`. /// Returns `self` with a length of `1.0`.
/// ///
/// Note that [`Rotation2d`] should typically already be normalized by design. /// Note that [`Rot2`] should typically already be normalized by design.
/// Manual normalization is only needed when successive operations result in /// Manual normalization is only needed when successive operations result in
/// accumulated floating point error, or if the rotation was constructed /// accumulated floating point error, or if the rotation was constructed
/// with invalid values. /// with invalid values.
@ -248,7 +249,7 @@ impl Rotation2d {
(self.length_squared() - 1.0).abs() <= 2e-4 (self.length_squared() - 1.0).abs() <= 2e-4
} }
/// Returns `true` if the rotation is near [`Rotation2d::IDENTITY`]. /// Returns `true` if the rotation is near [`Rot2::IDENTITY`].
#[inline] #[inline]
pub fn is_near_identity(self) -> bool { pub fn is_near_identity(self) -> bool {
// Same as `Quat::is_near_identity`, but using sine and cosine // Same as `Quat::is_near_identity`, but using sine and cosine
@ -300,10 +301,10 @@ impl Rotation2d {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use bevy_math::Rotation2d; /// # use bevy_math::Rot2;
/// # /// #
/// let rot1 = Rotation2d::IDENTITY; /// let rot1 = Rot2::IDENTITY;
/// let rot2 = Rotation2d::degrees(135.0); /// let rot2 = Rot2::degrees(135.0);
/// ///
/// let result1 = rot1.nlerp(rot2, 1.0 / 3.0); /// let result1 = rot1.nlerp(rot2, 1.0 / 3.0);
/// assert_eq!(result1.as_degrees(), 28.675055); /// assert_eq!(result1.as_degrees(), 28.675055);
@ -338,10 +339,10 @@ impl Rotation2d {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use bevy_math::Rotation2d; /// # use bevy_math::Rot2;
/// # /// #
/// let rot1 = Rotation2d::IDENTITY; /// let rot1 = Rot2::IDENTITY;
/// let rot2 = Rotation2d::degrees(135.0); /// let rot2 = Rot2::degrees(135.0);
/// ///
/// let result1 = rot1.slerp(rot2, 1.0 / 3.0); /// let result1 = rot1.slerp(rot2, 1.0 / 3.0);
/// assert_eq!(result1.as_degrees(), 45.0); /// assert_eq!(result1.as_degrees(), 45.0);
@ -355,21 +356,21 @@ impl Rotation2d {
} }
} }
impl From<f32> for Rotation2d { impl From<f32> for Rot2 {
/// Creates a [`Rotation2d`] from a counterclockwise angle in radians. /// Creates a [`Rot2`] from a counterclockwise angle in radians.
fn from(rotation: f32) -> Self { fn from(rotation: f32) -> Self {
Self::radians(rotation) Self::radians(rotation)
} }
} }
impl From<Rotation2d> for Mat2 { impl From<Rot2> for Mat2 {
/// Creates a [`Mat2`] rotation matrix from a [`Rotation2d`]. /// Creates a [`Mat2`] rotation matrix from a [`Rot2`].
fn from(rot: Rotation2d) -> Self { fn from(rot: Rot2) -> Self {
Mat2::from_cols_array(&[rot.cos, -rot.sin, rot.sin, rot.cos]) Mat2::from_cols_array(&[rot.cos, -rot.sin, rot.sin, rot.cos])
} }
} }
impl std::ops::Mul for Rotation2d { impl std::ops::Mul for Rot2 {
type Output = Self; type Output = Self;
fn mul(self, rhs: Self) -> Self::Output { fn mul(self, rhs: Self) -> Self::Output {
@ -380,16 +381,16 @@ impl std::ops::Mul for Rotation2d {
} }
} }
impl std::ops::MulAssign for Rotation2d { impl std::ops::MulAssign for Rot2 {
fn mul_assign(&mut self, rhs: Self) { fn mul_assign(&mut self, rhs: Self) {
*self = *self * rhs; *self = *self * rhs;
} }
} }
impl std::ops::Mul<Vec2> for Rotation2d { impl std::ops::Mul<Vec2> for Rot2 {
type Output = Vec2; type Output = Vec2;
/// Rotates a [`Vec2`] by a [`Rotation2d`]. /// Rotates a [`Vec2`] by a [`Rot2`].
fn mul(self, rhs: Vec2) -> Self::Output { fn mul(self, rhs: Vec2) -> Self::Output {
Vec2::new( Vec2::new(
rhs.x * self.cos - rhs.y * self.sin, rhs.x * self.cos - rhs.y * self.sin,
@ -399,7 +400,7 @@ impl std::ops::Mul<Vec2> for Rotation2d {
} }
#[cfg(any(feature = "approx", test))] #[cfg(any(feature = "approx", test))]
impl approx::AbsDiffEq for Rotation2d { impl approx::AbsDiffEq for Rot2 {
type Epsilon = f32; type Epsilon = f32;
fn default_epsilon() -> f32 { fn default_epsilon() -> f32 {
f32::EPSILON f32::EPSILON
@ -410,7 +411,7 @@ impl approx::AbsDiffEq for Rotation2d {
} }
#[cfg(any(feature = "approx", test))] #[cfg(any(feature = "approx", test))]
impl approx::RelativeEq for Rotation2d { impl approx::RelativeEq for Rot2 {
fn default_max_relative() -> f32 { fn default_max_relative() -> f32 {
f32::EPSILON f32::EPSILON
} }
@ -421,7 +422,7 @@ impl approx::RelativeEq for Rotation2d {
} }
#[cfg(any(feature = "approx", test))] #[cfg(any(feature = "approx", test))]
impl approx::UlpsEq for Rotation2d { impl approx::UlpsEq for Rot2 {
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {
4 4
} }
@ -435,13 +436,13 @@ impl approx::UlpsEq for Rotation2d {
mod tests { mod tests {
use approx::assert_relative_eq; use approx::assert_relative_eq;
use crate::{Dir2, Rotation2d, Vec2}; use crate::{Dir2, Rot2, Vec2};
#[test] #[test]
fn creation() { fn creation() {
let rotation1 = Rotation2d::radians(std::f32::consts::FRAC_PI_2); let rotation1 = Rot2::radians(std::f32::consts::FRAC_PI_2);
let rotation2 = Rotation2d::degrees(90.0); let rotation2 = Rot2::degrees(90.0);
let rotation3 = Rotation2d::from_sin_cos(1.0, 0.0); let rotation3 = Rot2::from_sin_cos(1.0, 0.0);
// All three rotations should be equal // All three rotations should be equal
assert_relative_eq!(rotation1.sin, rotation2.sin); assert_relative_eq!(rotation1.sin, rotation2.sin);
@ -456,7 +457,7 @@ mod tests {
#[test] #[test]
fn rotate() { fn rotate() {
let rotation = Rotation2d::degrees(90.0); let rotation = Rot2::degrees(90.0);
assert_relative_eq!(rotation * Vec2::X, Vec2::Y); assert_relative_eq!(rotation * Vec2::X, Vec2::Y);
assert_relative_eq!(rotation * Dir2::Y, Dir2::NEG_X); assert_relative_eq!(rotation * Dir2::Y, Dir2::NEG_X);
@ -464,8 +465,8 @@ mod tests {
#[test] #[test]
fn add() { fn add() {
let rotation1 = Rotation2d::degrees(90.0); let rotation1 = Rot2::degrees(90.0);
let rotation2 = Rotation2d::degrees(180.0); let rotation2 = Rot2::degrees(180.0);
// 90 deg + 180 deg becomes -90 deg after it wraps around to be within the ]-180, 180] range // 90 deg + 180 deg becomes -90 deg after it wraps around to be within the ]-180, 180] range
assert_eq!((rotation1 * rotation2).as_degrees(), -90.0); assert_eq!((rotation1 * rotation2).as_degrees(), -90.0);
@ -473,8 +474,8 @@ mod tests {
#[test] #[test]
fn subtract() { fn subtract() {
let rotation1 = Rotation2d::degrees(90.0); let rotation1 = Rot2::degrees(90.0);
let rotation2 = Rotation2d::degrees(45.0); let rotation2 = Rot2::degrees(45.0);
assert_relative_eq!((rotation1 * rotation2.inverse()).as_degrees(), 45.0); assert_relative_eq!((rotation1 * rotation2.inverse()).as_degrees(), 45.0);
@ -487,7 +488,7 @@ mod tests {
#[test] #[test]
fn length() { fn length() {
let rotation = Rotation2d { let rotation = Rot2 {
sin: 10.0, sin: 10.0,
cos: 5.0, cos: 5.0,
}; };
@ -499,16 +500,16 @@ mod tests {
#[test] #[test]
fn is_near_identity() { fn is_near_identity() {
assert!(!Rotation2d::radians(0.1).is_near_identity()); assert!(!Rot2::radians(0.1).is_near_identity());
assert!(!Rotation2d::radians(-0.1).is_near_identity()); assert!(!Rot2::radians(-0.1).is_near_identity());
assert!(Rotation2d::radians(0.00001).is_near_identity()); assert!(Rot2::radians(0.00001).is_near_identity());
assert!(Rotation2d::radians(-0.00001).is_near_identity()); assert!(Rot2::radians(-0.00001).is_near_identity());
assert!(Rotation2d::radians(0.0).is_near_identity()); assert!(Rot2::radians(0.0).is_near_identity());
} }
#[test] #[test]
fn normalize() { fn normalize() {
let rotation = Rotation2d { let rotation = Rot2 {
sin: 10.0, sin: 10.0,
cos: 5.0, cos: 5.0,
}; };
@ -524,7 +525,7 @@ mod tests {
#[test] #[test]
fn try_normalize() { fn try_normalize() {
// Valid // Valid
assert!(Rotation2d { assert!(Rot2 {
sin: 10.0, sin: 10.0,
cos: 5.0, cos: 5.0,
} }
@ -532,7 +533,7 @@ mod tests {
.is_some()); .is_some());
// NaN // NaN
assert!(Rotation2d { assert!(Rot2 {
sin: f32::NAN, sin: f32::NAN,
cos: 5.0, cos: 5.0,
} }
@ -540,10 +541,10 @@ mod tests {
.is_none()); .is_none());
// Zero // Zero
assert!(Rotation2d { sin: 0.0, cos: 0.0 }.try_normalize().is_none()); assert!(Rot2 { sin: 0.0, cos: 0.0 }.try_normalize().is_none());
// Non-finite // Non-finite
assert!(Rotation2d { assert!(Rot2 {
sin: f32::INFINITY, sin: f32::INFINITY,
cos: 5.0, cos: 5.0,
} }
@ -553,16 +554,16 @@ mod tests {
#[test] #[test]
fn nlerp() { fn nlerp() {
let rot1 = Rotation2d::IDENTITY; let rot1 = Rot2::IDENTITY;
let rot2 = Rotation2d::degrees(135.0); let rot2 = Rot2::degrees(135.0);
assert_eq!(rot1.nlerp(rot2, 1.0 / 3.0).as_degrees(), 28.675055); assert_eq!(rot1.nlerp(rot2, 1.0 / 3.0).as_degrees(), 28.675055);
assert!(rot1.nlerp(rot2, 0.0).is_near_identity()); assert!(rot1.nlerp(rot2, 0.0).is_near_identity());
assert_eq!(rot1.nlerp(rot2, 0.5).as_degrees(), 67.5); assert_eq!(rot1.nlerp(rot2, 0.5).as_degrees(), 67.5);
assert_eq!(rot1.nlerp(rot2, 1.0).as_degrees(), 135.0); assert_eq!(rot1.nlerp(rot2, 1.0).as_degrees(), 135.0);
let rot1 = Rotation2d::IDENTITY; let rot1 = Rot2::IDENTITY;
let rot2 = Rotation2d::from_sin_cos(0.0, -1.0); let rot2 = Rot2::from_sin_cos(0.0, -1.0);
assert!(rot1.nlerp(rot2, 1.0 / 3.0).is_near_identity()); assert!(rot1.nlerp(rot2, 1.0 / 3.0).is_near_identity());
assert!(rot1.nlerp(rot2, 0.0).is_near_identity()); assert!(rot1.nlerp(rot2, 0.0).is_near_identity());
@ -573,16 +574,16 @@ mod tests {
#[test] #[test]
fn slerp() { fn slerp() {
let rot1 = Rotation2d::IDENTITY; let rot1 = Rot2::IDENTITY;
let rot2 = Rotation2d::degrees(135.0); let rot2 = Rot2::degrees(135.0);
assert_eq!(rot1.slerp(rot2, 1.0 / 3.0).as_degrees(), 45.0); assert_eq!(rot1.slerp(rot2, 1.0 / 3.0).as_degrees(), 45.0);
assert!(rot1.slerp(rot2, 0.0).is_near_identity()); assert!(rot1.slerp(rot2, 0.0).is_near_identity());
assert_eq!(rot1.slerp(rot2, 0.5).as_degrees(), 67.5); assert_eq!(rot1.slerp(rot2, 0.5).as_degrees(), 67.5);
assert_eq!(rot1.slerp(rot2, 1.0).as_degrees(), 135.0); assert_eq!(rot1.slerp(rot2, 1.0).as_degrees(), 135.0);
let rot1 = Rotation2d::IDENTITY; let rot1 = Rot2::IDENTITY;
let rot2 = Rotation2d::from_sin_cos(0.0, -1.0); let rot2 = Rot2::from_sin_cos(0.0, -1.0);
assert!((rot1.slerp(rot2, 1.0 / 3.0).as_degrees() - 60.0).abs() < 10e-6); assert!((rot1.slerp(rot2, 1.0 / 3.0).as_degrees() - 60.0).abs() < 10e-6);
assert!(rot1.slerp(rot2, 0.0).is_near_identity()); assert!(rot1.slerp(rot2, 0.0).is_near_identity());

View file

@ -25,7 +25,7 @@ use std::f32::consts::TAU;
use crate::{ use crate::{
primitives::{Circle, Sphere}, primitives::{Circle, Sphere},
Dir2, Dir3, Dir3A, Quat, Rotation2d, ShapeSample, Vec3A, Dir2, Dir3, Dir3A, Quat, Rot2, ShapeSample, Vec3A,
}; };
use rand::{ use rand::{
distributions::{Distribution, Standard}, distributions::{Distribution, Standard},
@ -86,14 +86,14 @@ impl Distribution<Dir3A> for Standard {
impl FromRng for Dir3A {} impl FromRng for Dir3A {}
impl Distribution<Rotation2d> for Standard { impl Distribution<Rot2> for Standard {
#[inline] #[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Rotation2d { fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Rot2 {
let angle = rng.gen_range(0.0..TAU); let angle = rng.gen_range(0.0..TAU);
Rotation2d::radians(angle) Rot2::radians(angle)
} }
} }
impl FromRng for Rotation2d {} impl FromRng for Rot2 {}
impl FromRng for Quat {} impl FromRng for Quat {}