Switched to storing vertices as points and using a local to world function, instead of repeating myself.

This commit is contained in:
2025-08-28 13:42:22 -05:00
parent d7c4dea2cb
commit 2e340b7d28

View File

@@ -82,7 +82,7 @@ const ACCEL_STR: f64 = 1.;
struct Ship { struct Ship {
com_rotor: CGA, com_rotor: CGA,
verts: (CGA, CGA, CGA), verts: Vec::<CGA>,
vel: CGA, vel: CGA,
orientation: CGA, orientation: CGA,
} }
@@ -95,11 +95,7 @@ impl Ship {
let mut a_vec = - DRAG * &vel_2; let mut a_vec = - DRAG * &vel_2;
if keys.contains("w") { if keys.contains("w") {
let orient = &self.orientation; //Transforms body frame to local frame let accel_world = self.fixed_to_world(&(ACCEL_STR * CGA::e15()));
let pos = &self.com_rotor; //Transforms local frame to world frame
let accel_body = ACCEL_STR * CGA::e15(); //The acceleration in the body frame.
let accel_local = orient * accel_body * orient.Reverse(); //The acceleration in the local frame.
let accel_world = pos * accel_local * pos.Reverse(); //The acceleration in the world frame.
a_vec = a_vec - accel_world; //Sum of drag and thrust. a_vec = a_vec - accel_world; //Sum of drag and thrust.
} }
@@ -118,21 +114,16 @@ impl Ship {
let pos = bivector_exponential(&delta)*&self.com_rotor; //Update position. let pos = bivector_exponential(&delta)*&self.com_rotor; //Update position.
self.vel = vel_2; self.vel = vel_2;
self.com_rotor = pos; self.com_rotor = pos;
} }
fn draw(&self, context: &CanvasRenderingContext2d) { fn draw(&self, context: &CanvasRenderingContext2d) {
let origin = gen_hyperbolic_point(&CGA::zero()); //Origin in the body frame. let origin = gen_hyperbolic_point(&CGA::zero()); //Origin in the body frame.
let orient_rotor = &self.orientation; //Transforms body frame to local frame. let com = self.fixed_to_world(&origin);
let com = &self.com_rotor; //Transforms local frame to world frame. let p0 = self.fixed_to_world(&self.verts[0]);
let v0_rotor = com*orient_rotor*bivector_exponential(&self.verts.0); //Combined transformation to locate a vertex of the ship in the world frame. let p1 = self.fixed_to_world(&self.verts[1]);
let v1_rotor = com*orient_rotor*bivector_exponential(&self.verts.1); //Combined transformation ... let p2 = self.fixed_to_world(&self.verts[2]);
let v2_rotor = com*orient_rotor*bivector_exponential(&self.verts.2); //Combined transformation ...
let p0 = &v0_rotor*&origin*&v0_rotor.Reverse(); //Produce a vertex of the ship in the world frame.
let p1 = &v1_rotor*&origin*&v1_rotor.Reverse(); //...
let p2 = &v2_rotor*&origin*&v2_rotor.Reverse(); //...
draw_point(context, &(com*&origin*com.Reverse())); draw_point(context, &com);
draw_point(context, &p0); draw_point(context, &p0);
draw_point(context, &p1); draw_point(context, &p1);
draw_point(context, &p2); draw_point(context, &p2);
@@ -141,13 +132,14 @@ impl Ship {
draw_line_between(context, &p2, &p0); draw_line_between(context, &p2, &p0);
//Construct and draw line pointing straight ahead, to help orient the player. //Construct and draw line pointing straight ahead, to help orient the player.
let com_p = com * gen_hyperbolic_point(&CGA::zero()) * com.Reverse(); let delta_gen = self.fixed_to_world(&CGA::e14());
let delta_gen = com * orient_rotor * CGA::e14() * &orient_rotor.Reverse() * com.Reverse(); let dot = delta_gen | &com;
let dot = delta_gen | &com_p; let line = CGA::e4() ^ com ^ dot;
let line = CGA::e4() ^ com_p ^ dot;// ^ CGA::e3();
draw_line(context, &line); draw_line(context, &line);
}
fn fixed_to_world(&self, vec: &CGA) -> CGA {
&self.com_rotor * &self.orientation * vec * &self.orientation.Reverse() * &self.com_rotor.Reverse()
} }
} }
@@ -554,9 +546,21 @@ impl Game {
let tx_gen = CGA::e15(); let tx_gen = CGA::e15();
let ty_gen = CGA::e25(); let ty_gen = CGA::e25();
let v1_gen = -0.1*&tx_gen;
let v2_gen = 0.05*&tx_gen+0.02*&ty_gen;
let v3_gen = 0.05*&tx_gen-0.02*&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 ship = Ship { let ship = Ship {
com_rotor: CGA::new(1., SCALAR), com_rotor: CGA::new(1., SCALAR),
verts: (-0.1*&tx_gen, 0.05*&tx_gen+0.02*&ty_gen, 0.05*&tx_gen-0.02*ty_gen), verts: vec![ v1, v2, v3],
vel: CGA::zero(), vel: CGA::zero(),
orientation: CGA::new(1., SCALAR), orientation: CGA::new(1., SCALAR),
}; };