mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 12:13:25 +00:00
Implement Measured2d
for Arc2d
-based primitives. (#16213)
# Objective - `CircularSegment` and `CircularSector` are well defined 2D shapes with both an area and a perimeter. # Solution - This PR implements `perimeter` for both and moves the existsing `area` functions into the `Measured2d` implementations. ## Testing - The `arc_tests` have been extended to also check for perimeters.
This commit is contained in:
parent
565616622b
commit
52b8b55c2d
1 changed files with 42 additions and 12 deletions
|
@ -292,6 +292,22 @@ impl Default for CircularSector {
|
|||
}
|
||||
}
|
||||
|
||||
impl Measured2d for CircularSector {
|
||||
#[inline(always)]
|
||||
fn area(&self) -> f32 {
|
||||
self.arc.radius.squared() * self.arc.half_angle
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn perimeter(&self) -> f32 {
|
||||
if self.half_angle() >= PI {
|
||||
self.arc.radius * 2.0 * PI
|
||||
} else {
|
||||
2.0 * self.radius() + self.arc_length()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CircularSector {
|
||||
/// Create a new [`CircularSector`] from a `radius` and an `angle`
|
||||
#[inline(always)]
|
||||
|
@ -382,12 +398,6 @@ impl CircularSector {
|
|||
pub fn sagitta(&self) -> f32 {
|
||||
self.arc.sagitta()
|
||||
}
|
||||
|
||||
/// Returns the area of this sector
|
||||
#[inline(always)]
|
||||
pub fn area(&self) -> f32 {
|
||||
self.arc.radius.squared() * self.arc.half_angle
|
||||
}
|
||||
}
|
||||
|
||||
/// A primitive representing a circular segment:
|
||||
|
@ -425,6 +435,17 @@ impl Default for CircularSegment {
|
|||
}
|
||||
}
|
||||
|
||||
impl Measured2d for CircularSegment {
|
||||
#[inline(always)]
|
||||
fn area(&self) -> f32 {
|
||||
0.5 * self.arc.radius.squared() * (self.arc.angle() - ops::sin(self.arc.angle()))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn perimeter(&self) -> f32 {
|
||||
self.chord_length() + self.arc_length()
|
||||
}
|
||||
}
|
||||
impl CircularSegment {
|
||||
/// Create a new [`CircularSegment`] from a `radius`, and an `angle`
|
||||
#[inline(always)]
|
||||
|
@ -515,17 +536,12 @@ impl CircularSegment {
|
|||
pub fn sagitta(&self) -> f32 {
|
||||
self.arc.sagitta()
|
||||
}
|
||||
|
||||
/// Returns the area of this segment
|
||||
#[inline(always)]
|
||||
pub fn area(&self) -> f32 {
|
||||
0.5 * self.arc.radius.squared() * (self.arc.angle() - ops::sin(self.arc.angle()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod arc_tests {
|
||||
use core::f32::consts::FRAC_PI_4;
|
||||
use core::f32::consts::SQRT_2;
|
||||
|
||||
use approx::assert_abs_diff_eq;
|
||||
|
||||
|
@ -548,7 +564,9 @@ mod arc_tests {
|
|||
is_minor: bool,
|
||||
is_major: bool,
|
||||
sector_area: f32,
|
||||
sector_perimeter: f32,
|
||||
segment_area: f32,
|
||||
segment_perimeter: f32,
|
||||
}
|
||||
|
||||
impl ArcTestCase {
|
||||
|
@ -581,6 +599,7 @@ mod arc_tests {
|
|||
assert_abs_diff_eq!(self.apothem, sector.apothem());
|
||||
assert_abs_diff_eq!(self.sagitta, sector.sagitta());
|
||||
assert_abs_diff_eq!(self.sector_area, sector.area());
|
||||
assert_abs_diff_eq!(self.sector_perimeter, sector.perimeter());
|
||||
}
|
||||
|
||||
fn check_segment(&self, segment: CircularSegment) {
|
||||
|
@ -593,6 +612,7 @@ mod arc_tests {
|
|||
assert_abs_diff_eq!(self.apothem, segment.apothem());
|
||||
assert_abs_diff_eq!(self.sagitta, segment.sagitta());
|
||||
assert_abs_diff_eq!(self.segment_area, segment.area());
|
||||
assert_abs_diff_eq!(self.segment_perimeter, segment.perimeter());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,7 +635,9 @@ mod arc_tests {
|
|||
is_minor: true,
|
||||
is_major: false,
|
||||
sector_area: 0.0,
|
||||
sector_perimeter: 2.0,
|
||||
segment_area: 0.0,
|
||||
segment_perimeter: 0.0,
|
||||
};
|
||||
|
||||
tests.check_arc(Arc2d::new(1.0, 0.0));
|
||||
|
@ -642,7 +664,9 @@ mod arc_tests {
|
|||
is_minor: true,
|
||||
is_major: false,
|
||||
sector_area: 0.0,
|
||||
sector_perimeter: 0.0,
|
||||
segment_area: 0.0,
|
||||
segment_perimeter: 0.0,
|
||||
};
|
||||
|
||||
tests.check_arc(Arc2d::new(0.0, FRAC_PI_4));
|
||||
|
@ -670,7 +694,9 @@ mod arc_tests {
|
|||
is_minor: true,
|
||||
is_major: false,
|
||||
sector_area: FRAC_PI_4,
|
||||
sector_perimeter: FRAC_PI_2 + 2.0,
|
||||
segment_area: FRAC_PI_4 - 0.5,
|
||||
segment_perimeter: FRAC_PI_2 + SQRT_2,
|
||||
};
|
||||
|
||||
tests.check_arc(Arc2d::from_turns(1.0, 0.25));
|
||||
|
@ -697,7 +723,9 @@ mod arc_tests {
|
|||
is_minor: true,
|
||||
is_major: true,
|
||||
sector_area: FRAC_PI_2,
|
||||
sector_perimeter: PI + 2.0,
|
||||
segment_area: FRAC_PI_2,
|
||||
segment_perimeter: PI + 2.0,
|
||||
};
|
||||
|
||||
tests.check_arc(Arc2d::from_radians(1.0, PI));
|
||||
|
@ -724,7 +752,9 @@ mod arc_tests {
|
|||
is_minor: false,
|
||||
is_major: true,
|
||||
sector_area: PI,
|
||||
sector_perimeter: 2.0 * PI,
|
||||
segment_area: PI,
|
||||
segment_perimeter: 2.0 * PI,
|
||||
};
|
||||
|
||||
tests.check_arc(Arc2d::from_degrees(1.0, 360.0));
|
||||
|
|
Loading…
Reference in a new issue