Adjusted code so asteroids should correctly follow geodesics.
This commit is contained in:
112
src/lib.rs
112
src/lib.rs
@@ -552,7 +552,8 @@ fn bivector_exponential(bivector: &CGA) -> CGA {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Asteroid {
|
struct Asteroid {
|
||||||
circle: CGA,
|
com_rotor: CGA,
|
||||||
|
verts: Vec::<CGA>,
|
||||||
vel: CGA,
|
vel: CGA,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,28 +570,106 @@ fn circle_from_coords(x: f64, y: f64, r: f64) -> CGA {
|
|||||||
|
|
||||||
impl Asteroid {
|
impl Asteroid {
|
||||||
fn new() -> Asteroid {
|
fn new() -> Asteroid {
|
||||||
let v = 0.;
|
let vec = 0.8*CGA::e1() + 0.0*CGA::e2();
|
||||||
|
let vec_sqr = (&vec*&vec)[SCALAR];
|
||||||
|
let scale = 1. / (1.-vec_sqr).sqrt();
|
||||||
|
let com_rotor = scale * (CGA::new(1., SCALAR) + CGA::e5()*vec);
|
||||||
|
let tx_gen = CGA::e15();
|
||||||
|
let ty_gen = CGA::e25();
|
||||||
|
let v1_gen = -0.2*&tx_gen;
|
||||||
|
let v2_gen = 0.2*&tx_gen;
|
||||||
|
let v3_gen = 0.2*&ty_gen;
|
||||||
|
let v1_rot = bivector_exponential(&v1_gen);
|
||||||
|
let v2_rot = bivector_exponential(&v2_gen);
|
||||||
|
let v3_rot = bivector_exponential(&v3_gen);
|
||||||
|
|
||||||
|
let origin = gen_hyperbolic_point(&CGA::zero());
|
||||||
|
let v1 = &v1_rot * &origin * &v1_rot.Reverse();
|
||||||
|
let v2 = &v2_rot * &origin * &v2_rot.Reverse();
|
||||||
|
let v3 = &v3_rot * &origin * &v3_rot.Reverse();
|
||||||
|
let verts = vec![v1, v2, v3];
|
||||||
|
|
||||||
|
let v = 1.;
|
||||||
let (v_x, v_y) = (v * 1.0_f64.cos(), v*1.0_f64.sin());
|
let (v_x, v_y) = (v * 1.0_f64.cos(), v*1.0_f64.sin());
|
||||||
let vel = v_x*CGA::e15() + v_y*CGA::e25();
|
let vel = v_x*CGA::e1() + v_y*CGA::e2();
|
||||||
let circle = circle_from_coords(0.5, 0., 0.4);
|
Asteroid { com_rotor, vel, verts }
|
||||||
Asteroid { circle, vel }
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
fn _new_from_coords(x: f64, y: f64, r: f64, vel: CGA) -> Asteroid {
|
fn _new_from_coords(x: f64, y: f64, r: f64, vel: CGA) -> Asteroid {
|
||||||
let circle = circle_from_coords(x, y, r);
|
let (circle, verts) = circle_from_coords(x, y, r);
|
||||||
Asteroid { circle, vel }
|
Asteroid { circle, vel, verts }
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
fn update(&mut self, dt_s: f64) {
|
fn update(&mut self, dt_s: f64, boundary: &CGA) {
|
||||||
let vel = &self.vel;
|
let vel = &self.vel*CGA::e5();
|
||||||
let delta = vel * dt_s;
|
let delta = &vel * dt_s;
|
||||||
|
let delta = self.fixed_to_world(&delta);//&self.com_rotor * delta * &self.com_rotor.Reverse();
|
||||||
let vel_rotor = bivector_exponential(&delta);
|
let vel_rotor = bivector_exponential(&delta);
|
||||||
let circle = &vel_rotor*&self.circle*&vel_rotor.Reverse();
|
//let vel_rotor = &self.com_rotor.Reverse() * vel_rotor * &self.com_rotor;
|
||||||
self.circle = circle;
|
let new_pos = &vel_rotor * &self.com_rotor;
|
||||||
|
let p1 = &new_pos * &self.verts[0] * &new_pos.Reverse();
|
||||||
|
let p2 = &new_pos * &self.verts[1] * &new_pos.Reverse();
|
||||||
|
let p3 = &new_pos * &self.verts[2] * &new_pos.Reverse();
|
||||||
|
let circle = p1 ^ p2 ^ p3;
|
||||||
|
let intersect = circle_intersection(&circle, boundary);
|
||||||
|
match intersect {
|
||||||
|
CircleIntersection::None => { self.com_rotor = new_pos; }
|
||||||
|
CircleIntersection::TwoPoints(_,_) => {
|
||||||
|
self.reflect_off_boundary();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, context: &CanvasRenderingContext2d) {
|
fn draw(&self, context: &CanvasRenderingContext2d) {
|
||||||
draw_line(context, &self.circle);
|
let p1 = self.fixed_to_world(&self.verts[0]);
|
||||||
|
let p2 = self.fixed_to_world(&self.verts[1]);
|
||||||
|
let p3 = self.fixed_to_world(&self.verts[2]);
|
||||||
|
draw_point(context, &p1);
|
||||||
|
draw_point(context, &p2);
|
||||||
|
draw_point(context, &p3);
|
||||||
|
let circle = &p1 ^ &p2 ^ &p3;
|
||||||
|
draw_line(context, &circle);
|
||||||
|
//Construct and draw line pointing straight ahead, to help orient the player.
|
||||||
|
let origin = gen_hyperbolic_point(&CGA::zero());
|
||||||
|
let com = self.fixed_to_world(&origin);
|
||||||
|
let delta_gen = self.fixed_to_world(&(&self.vel*CGA::e5()));
|
||||||
|
let dot = delta_gen | &com;
|
||||||
|
let line = CGA::e4() ^ com ^ dot;
|
||||||
|
draw_line(context, &line);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fixed_to_world(&self, vec: &CGA) -> CGA {
|
||||||
|
&self.com_rotor*vec*&self.com_rotor.Reverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_circle(&self) -> CGA {
|
||||||
|
let p1 = self.fixed_to_world(&self.verts[0]);
|
||||||
|
let p2 = self.fixed_to_world(&self.verts[1]);
|
||||||
|
let p3 = self.fixed_to_world(&self.verts[2]);
|
||||||
|
p1 ^ p2 ^ p3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reflect_off_boundary(&mut self) {
|
||||||
|
let origin = gen_hyperbolic_point(&CGA::zero());
|
||||||
|
let mut pos = self.fixed_to_world(&origin);
|
||||||
|
pos[E4] = 0.;
|
||||||
|
pos[E5] = 0.;
|
||||||
|
let norm = pos.norm();
|
||||||
|
pos = pos * (1./ norm);
|
||||||
|
let norm_old = self.vel.norm();
|
||||||
|
let vel = self.fixed_to_world(&self.vel);
|
||||||
|
let dot = &vel | &pos;
|
||||||
|
let vel_para_radial = dot * &pos;
|
||||||
|
let vel_perp_radial = &vel - &vel_para_radial;
|
||||||
|
let vel_tick = vel_perp_radial - vel_para_radial;
|
||||||
|
let mut vel_fixed = &self.com_rotor.Reverse()*vel_tick*&self.com_rotor;
|
||||||
|
vel_fixed[E4] = 0.;
|
||||||
|
vel_fixed[E5] = 0.;
|
||||||
|
let norm = vel_fixed.norm();
|
||||||
|
vel_fixed = (1. / norm)*vel_fixed;
|
||||||
|
vel_fixed = norm_old * vel_fixed;
|
||||||
|
self.vel = vel_fixed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +754,8 @@ impl Game {
|
|||||||
|
|
||||||
self.context.set_stroke_style_str(RED);
|
self.context.set_stroke_style_str(RED);
|
||||||
for asteroid in &self.asteroids {
|
for asteroid in &self.asteroids {
|
||||||
if self.ship.intersects_circle(&asteroid.circle) {
|
let circle = asteroid.get_circle();
|
||||||
|
if self.ship.intersects_circle(&circle) {
|
||||||
intersects = true;
|
intersects = true;
|
||||||
}
|
}
|
||||||
asteroid.draw(&self.context);
|
asteroid.draw(&self.context);
|
||||||
@@ -699,7 +779,7 @@ impl Game {
|
|||||||
self.dt = dt_m;
|
self.dt = dt_m;
|
||||||
|
|
||||||
for asteroid in &mut self.asteroids {
|
for asteroid in &mut self.asteroids {
|
||||||
asteroid.update(dt_s);
|
asteroid.update(dt_s, &self.boundary);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ship.update(dt_s, &self.keys, &self.boundary);
|
self.ship.update(dt_s, &self.keys, &self.boundary);
|
||||||
|
|||||||
Reference in New Issue
Block a user