Add `emath::fast_midpoint` (#7435)
This commit is contained in:
parent
3024c39eaf
commit
6fae65a3fa
|
|
@ -300,7 +300,7 @@ zero_sized_map_values = "warn"
|
||||||
# doc_comment_double_space_linebreaks = "warn"
|
# doc_comment_double_space_linebreaks = "warn"
|
||||||
# elidable_lifetime_names = "warn"
|
# elidable_lifetime_names = "warn"
|
||||||
# ignore_without_reason = "warn"
|
# ignore_without_reason = "warn"
|
||||||
# manual_midpoint = "warn"
|
# manual_midpoint = "warn" # NOTE `midpoint` is often a lot slower for floats, so we have our own `emath::fast_midpoint` function.
|
||||||
# non_std_lazy_statics = "warn"
|
# non_std_lazy_statics = "warn"
|
||||||
# precedence_bits = "warn"
|
# precedence_bits = "warn"
|
||||||
# return_and_then = "warn"
|
# return_and_then = "warn"
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ impl Align {
|
||||||
if size == f32::INFINITY {
|
if size == f32::INFINITY {
|
||||||
Rangef::new(f32::NEG_INFINITY, f32::INFINITY)
|
Rangef::new(f32::NEG_INFINITY, f32::INFINITY)
|
||||||
} else {
|
} else {
|
||||||
let left = f32::midpoint(min, max) - size / 2.0;
|
let left = crate::fast_midpoint(min, max) - size / 2.0;
|
||||||
Rangef::new(left, left + size)
|
Rangef::new(left, left + size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,21 @@ where
|
||||||
(T::ONE - t) * *range.start() + t * *range.end()
|
(T::ONE - t) * *range.start() + t * *range.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is a faster version of [`f32::midpoint`] which doesn't handle overflow.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use emath::fast_midpoint;
|
||||||
|
/// assert_eq!(fast_midpoint(1.0, 5.0), 3.0);
|
||||||
|
/// ```
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn fast_midpoint<R>(a: R, b: R) -> R
|
||||||
|
where
|
||||||
|
R: Copy + Add<R, Output = R> + Div<R, Output = R> + One,
|
||||||
|
{
|
||||||
|
let two = R::ONE + R::ONE;
|
||||||
|
(a + b) / two
|
||||||
|
}
|
||||||
|
|
||||||
/// Where in the range is this value? Returns 0-1 if within the range.
|
/// Where in the range is this value? Returns 0-1 if within the range.
|
||||||
///
|
///
|
||||||
/// Returns <0 if before and >1 if after.
|
/// Returns <0 if before and >1 if after.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::{Div, Mul, NumExt as _, Pos2, Rangef, Rot2, Vec2, lerp, pos2, vec2};
|
use crate::{Div, Mul, NumExt as _, Pos2, Rangef, Rot2, Vec2, fast_midpoint, lerp, pos2, vec2};
|
||||||
use std::ops::{BitOr, BitOrAssign};
|
use std::ops::{BitOr, BitOrAssign};
|
||||||
|
|
||||||
/// A rectangular region of space.
|
/// A rectangular region of space.
|
||||||
|
|
@ -331,8 +331,8 @@ impl Rect {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn center(&self) -> Pos2 {
|
pub fn center(&self) -> Pos2 {
|
||||||
Pos2 {
|
Pos2 {
|
||||||
x: f32::midpoint(self.min.x, self.max.x),
|
x: fast_midpoint(self.min.x, self.max.x),
|
||||||
y: f32::midpoint(self.min.y, self.max.y),
|
y: fast_midpoint(self.min.y, self.max.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
//! Find "simple" numbers is some range. Used by sliders.
|
//! Find "simple" numbers is some range. Used by sliders.
|
||||||
|
|
||||||
|
use crate::fast_midpoint;
|
||||||
|
|
||||||
const NUM_DECIMALS: usize = 15;
|
const NUM_DECIMALS: usize = 15;
|
||||||
|
|
||||||
/// Find the "simplest" number in a closed range [min, max], i.e. the one with the fewest decimal digits.
|
/// Find the "simplest" number in a closed range [min, max], i.e. the one with the fewest decimal digits.
|
||||||
|
|
@ -43,7 +45,7 @@ pub fn best_in_range_f64(min: f64, max: f64) -> f64 {
|
||||||
|
|
||||||
if min_exponent.floor() != max_exponent.floor() {
|
if min_exponent.floor() != max_exponent.floor() {
|
||||||
// pick the geometric center of the two:
|
// pick the geometric center of the two:
|
||||||
let exponent = f64::midpoint(min_exponent, max_exponent);
|
let exponent = fast_midpoint(min_exponent, max_exponent);
|
||||||
return 10.0_f64.powi(exponent.round() as i32);
|
return 10.0_f64.powi(exponent.round() as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue