Move normalize_angle to emath

This commit is contained in:
Emil Ernerfeldt 2021-05-08 23:42:17 +02:00
parent dd6980bacb
commit 4bb79a7047
2 changed files with 40 additions and 29 deletions

View file

@ -1,11 +1,10 @@
use std::{
collections::BTreeMap,
f32::consts::{PI, TAU},
fmt::Debug,
};
use std::{collections::BTreeMap, fmt::Debug};
use crate::{data::input::TouchDeviceId, Event, RawInput, TouchId, TouchPhase};
use epaint::emath::{Pos2, Vec2};
use crate::{
data::input::TouchDeviceId,
emath::{normalized_angle, Pos2, Vec2},
Event, RawInput, TouchId, TouchPhase,
};
/// All you probably need to know about a multi-touch gesture.
pub struct MultiTouchInfo {
@ -196,7 +195,7 @@ impl TouchState {
num_touches: self.active_touches.len(),
zoom_delta,
zoom_delta_2d: zoom_delta2,
rotation_delta: normalized_angle(state.current.heading, state_previous.heading),
rotation_delta: normalized_angle(state.current.heading - state_previous.heading),
translation_delta: state.current.avg_pos - state_previous.avg_pos,
force: state.current.avg_force,
}
@ -294,27 +293,6 @@ impl Debug for TouchState {
}
}
/// Calculate difference between two directions, such that the absolute value of the result is
/// minimized.
fn normalized_angle(current_direction: f32, previous_direction: f32) -> f32 {
let mut angle = current_direction - previous_direction;
angle %= TAU;
if angle > PI {
angle -= TAU;
} else if angle < -PI {
angle += TAU;
}
angle
}
#[test]
fn normalizing_angle_from_350_to_0_yields_10() {
assert!(
(normalized_angle(0_f32.to_radians(), 350_f32.to_radians()) - 10_f32.to_radians()).abs()
<= 5. * f32::EPSILON // many conversions (=divisions) involved => high error rate
);
}
#[derive(Clone, Debug)]
enum PinchType {
Horizontal,

View file

@ -331,3 +331,36 @@ impl_num_ext!(f64);
impl_num_ext!(usize);
impl_num_ext!(Vec2);
impl_num_ext!(Pos2);
// ----------------------------------------------------------------------------
/// Wrap angle to `[-PI, PI]` range.
pub fn normalized_angle(mut angle: f32) -> f32 {
use std::f32::consts::{PI, TAU};
angle %= TAU;
if angle > PI {
angle -= TAU;
} else if angle < -PI {
angle += TAU;
}
angle
}
#[test]
fn test_normalized_angle() {
macro_rules! almost_eq {
($left:expr, $right:expr) => {
let left = $left;
let right = $right;
assert!((left - right).abs() < 1e-6, "{} != {}", left, right);
};
}
use std::f32::consts::TAU;
almost_eq!(normalized_angle(-3.0 * TAU), 0.0);
almost_eq!(normalized_angle(-2.3 * TAU), -0.3 * TAU);
almost_eq!(normalized_angle(-TAU), 0.0);
almost_eq!(normalized_angle(0.0), 0.0);
almost_eq!(normalized_angle(TAU), 0.0);
almost_eq!(normalized_angle(2.7 * TAU), -0.3 * TAU);
}