Add put_object
This commit is contained in:
parent
0c0e22423d
commit
f5f94d3c1c
|
|
@ -146,6 +146,49 @@ fn rel_to_abs(space: &impl Metric, base: &Location, rel: Vec2, steps: usize) ->
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a position and a rotation to a [Location]. Only the X direction is preserved from `rot` to ensure the resulting Location describes an orthonormal coordinate system.
|
||||||
|
///
|
||||||
|
/// Mathematically, returned `rot` is `M^-1 * orthonormalize(M * rot)` where `M^2` is the metric tensor.
|
||||||
|
fn put_object(space: &impl Metric, pos: Vec2, rot: Mat2) -> Location {
|
||||||
|
let x_dir = rot.x_axis;
|
||||||
|
let metric_sqrt = Mat2::from(space.sqrt_at(pos));
|
||||||
|
let metric_inv_sqrt = Mat2::from(space.sqrt_at(pos).inverse());
|
||||||
|
let fx = (metric_sqrt * x_dir).normalize();
|
||||||
|
let fy = vec2(-fx.y, fx.x); // TODO: respect orientation of `rot`
|
||||||
|
let rot = metric_inv_sqrt * mat2(fx, fy);
|
||||||
|
Location { pos, rot }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_put_object() {
|
||||||
|
use approx::assert_abs_diff_eq;
|
||||||
|
|
||||||
|
let ε = 1e-5;
|
||||||
|
let m = riemann::samples::ScaledMetric {
|
||||||
|
scale: vec2(3., 4.),
|
||||||
|
};
|
||||||
|
|
||||||
|
let loc = put_object(&m, vec2(1., 2.), mat2(vec2(1., 0.), vec2(0., 1.)));
|
||||||
|
assert_eq!(loc.pos, vec2(1., 2.));
|
||||||
|
assert_abs_diff_eq!(loc.rot * vec2(1., 0.), vec2(1. / 3., 0.), epsilon = ε);
|
||||||
|
assert_abs_diff_eq!(loc.rot * vec2(0., 1.), vec2(0., 1. / 4.), epsilon = ε);
|
||||||
|
|
||||||
|
let loc = put_object(&m, vec2(1., 2.), mat2(vec2(0., 1.), vec2(-1., 0.)));
|
||||||
|
assert_eq!(loc.pos, vec2(1., 2.));
|
||||||
|
assert_abs_diff_eq!(loc.rot * vec2(1., 0.), vec2(0., 1. / 4.), epsilon = ε);
|
||||||
|
assert_abs_diff_eq!(loc.rot * vec2(0., 1.), vec2(-1. / 3., 0.), epsilon = ε);
|
||||||
|
|
||||||
|
let c = 0.5 * std::f32::consts::SQRT_2;
|
||||||
|
let loc = put_object(&m, vec2(1., 2.), mat2(vec2(c, c), vec2(-c, c)));
|
||||||
|
assert_eq!(loc.pos, vec2(1., 2.));
|
||||||
|
assert_abs_diff_eq!(loc.rot * vec2(1., 0.), vec2(1. / 5., 1. / 5.), epsilon = ε);
|
||||||
|
assert_abs_diff_eq!(
|
||||||
|
loc.rot * vec2(0., 1.),
|
||||||
|
vec2(-4. / 15., 3. / 20.),
|
||||||
|
epsilon = ε
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_cross(gc: &mut Vec<Draw>, pos: Vec2, r: f32) {
|
fn draw_cross(gc: &mut Vec<Draw>, pos: Vec2, r: f32) {
|
||||||
gc.move_to(pos.x - r, pos.y - r);
|
gc.move_to(pos.x - r, pos.y - r);
|
||||||
gc.line_to(pos.x + r, pos.y + r);
|
gc.line_to(pos.x + r, pos.y + r);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user