mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix issue with angle between going over PI and remove faulty test (angle between Quaternions isn't equivalent to the angle between Dir vectors since Quaternions involve rolling as well)
This commit is contained in:
parent
aa1ffa9f61
commit
c412a96d6a
@ -1,8 +1,8 @@
|
|||||||
use crate::util::{Dir, Plane, Projection};
|
use crate::util::{Dir, Plane, Projection};
|
||||||
|
use core::f32::consts::{FRAC_PI_2, PI, TAU};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::Component;
|
use specs::Component;
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
use std::f32::consts::{FRAC_PI_2, PI};
|
|
||||||
use vek::{Quaternion, Vec2, Vec3};
|
use vek::{Quaternion, Vec2, Vec3};
|
||||||
|
|
||||||
// Orientation
|
// Orientation
|
||||||
@ -189,6 +189,10 @@ impl Ori {
|
|||||||
|
|
||||||
/// Find the angle between two `Ori`s
|
/// Find the angle between two `Ori`s
|
||||||
///
|
///
|
||||||
|
/// NOTE: This finds the angle of the quaternion between the two `Ori`s
|
||||||
|
/// which can involve rolling and thus can be larger than simply the
|
||||||
|
/// angle between vectors at the start and end points.
|
||||||
|
///
|
||||||
/// Returns angle in radians
|
/// Returns angle in radians
|
||||||
pub fn angle_between(self, other: Self) -> f32 {
|
pub fn angle_between(self, other: Self) -> f32 {
|
||||||
// Compute quaternion from one ori to the other
|
// Compute quaternion from one ori to the other
|
||||||
@ -196,7 +200,8 @@ impl Ori {
|
|||||||
let between = self.to_quat().conjugate() * other.to_quat();
|
let between = self.to_quat().conjugate() * other.to_quat();
|
||||||
// Then compute it's angle
|
// Then compute it's angle
|
||||||
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/
|
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/
|
||||||
2.0 * between.w.acos()
|
let angle = 2.0 * between.w.acos();
|
||||||
|
if angle < PI { angle } else { TAU - angle }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pitched_up(self, angle_radians: f32) -> Self {
|
pub fn pitched_up(self, angle_radians: f32) -> Self {
|
||||||
@ -470,20 +475,6 @@ mod tests {
|
|||||||
dirs().for_each(to_horizontal);
|
dirs().for_each(to_horizontal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn angle_between() {
|
|
||||||
let angle_between = |(dir_a, dir_b): (Dir, Dir)| {
|
|
||||||
let ori_a = Ori::from(dir_a);
|
|
||||||
let ori_b = Ori::from(dir_b);
|
|
||||||
|
|
||||||
approx::assert_relative_eq!(ori_a.angle_between(ori_b), dir_a.angle_between(*dir_b));
|
|
||||||
};
|
|
||||||
|
|
||||||
dirs()
|
|
||||||
.flat_map(|dir| dirs().map(move |dir_two| (dir, dir_two)))
|
|
||||||
.for_each(angle_between)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_to_dir() {
|
fn from_to_dir() {
|
||||||
let from_to = |dir: Dir| {
|
let from_to = |dir: Dir| {
|
||||||
|
Loading…
Reference in New Issue
Block a user