Improved geometry finding to be more pedagogical. Minor modifications to remove some warnings.
This commit is contained in:
71
src/lib.rs
71
src/lib.rs
@@ -30,7 +30,7 @@ use cga::CGA;
|
||||
|
||||
const PI: f64 = f64::consts::PI;
|
||||
const TWO_PI: f64 = 2.*PI;
|
||||
const ERROR: f64 = 0.0001;
|
||||
const ERROR: f64 = 0.000001;
|
||||
|
||||
const WIDTH: f64 = 600.;
|
||||
const HEIGHT: f64 = 600.;
|
||||
@@ -144,7 +144,7 @@ impl Ship {
|
||||
let com_p = com * gen_hyperbolic_point(&CGA::zero()) * com.Reverse();
|
||||
let delta_gen = com * orient_rotor * CGA::e14() * &orient_rotor.Reverse() * com.Reverse();
|
||||
let dot = delta_gen | &com_p;
|
||||
let line = CGA::e4() ^ com_p ^ dot ^ CGA::e3();
|
||||
let line = CGA::e4() ^ com_p ^ dot;// ^ CGA::e3();
|
||||
draw_line(context, &line);
|
||||
|
||||
|
||||
@@ -153,8 +153,7 @@ impl Ship {
|
||||
|
||||
enum Geometry {
|
||||
Circle(f64, f64, f64), //x,y,r
|
||||
Line(f64, f64, f64), //x,r,theta
|
||||
Null,
|
||||
Line(f64, f64, f64), //x,y,theta
|
||||
}
|
||||
|
||||
/* Translation of a Euclidean Point. Need to use hyperbolic*/
|
||||
@@ -242,33 +241,31 @@ fn get_point(point: &CGA) -> (f64, f64) {
|
||||
(x/norm, y/norm)
|
||||
}
|
||||
|
||||
fn get_geometry(circle: &CGA) -> Geometry {
|
||||
//Naively assume we are given a valid line/circle
|
||||
fn get_geometry(trivector: &CGA) -> Geometry {
|
||||
let trivector = grade_selection(trivector, 3);
|
||||
let i4 = CGA::e1() ^ CGA::e2() ^ CGA::e4() ^ CGA::e5(); //Left out e3 intentionally
|
||||
let i2 = CGA::e1() ^ CGA::e2();
|
||||
let n_bar = CGA::e4() - CGA::e5();
|
||||
let n_vec = CGA::e4() + CGA::e5();
|
||||
let dual = (&circle).Dual();
|
||||
let l = (&dual | &n_vec)[SCALAR];
|
||||
let c = (&dual | &n_bar)[SCALAR];
|
||||
let a = (&dual | CGA::e1())[SCALAR];
|
||||
let b = (&dual | CGA::e2())[SCALAR];
|
||||
|
||||
if l.abs() < ERROR {
|
||||
//LINE
|
||||
let theta = (-a).atan2(b);
|
||||
let norm_sqr = a*a + b*b;
|
||||
if norm_sqr < ERROR*ERROR {
|
||||
return Geometry::Null;
|
||||
}
|
||||
let x = a*c/norm_sqr/2.;
|
||||
let y = b*c/norm_sqr/2.;
|
||||
return Geometry::Line(x,y,theta);
|
||||
let wedge = &trivector ^ &n_vec;
|
||||
let mag = magnitude(&wedge);
|
||||
let dual = &trivector * &i4;
|
||||
if mag < ERROR {
|
||||
//Line
|
||||
let d = 0.5*(&dual | &n_bar)[SCALAR];
|
||||
let m = -1.*(&dual - 0.5*d*&n_vec)*&i2;
|
||||
let theta = (m[E2]).atan2(m[E1]);
|
||||
return Geometry::Line(0., -d/m[E1], theta);
|
||||
} else {
|
||||
//Circle
|
||||
let c_x = a/l;
|
||||
let c_y = b/l;
|
||||
let r_sqr = c_x*c_x + c_y*c_y + c/l;
|
||||
let r = r_sqr.sqrt();
|
||||
return Geometry::Circle(-c_x, -c_y, r);
|
||||
let normalize = -(&dual | &n_vec)[SCALAR];
|
||||
let dual = dual * (1.0/normalize);
|
||||
let center = &trivector * &n_vec * &trivector;
|
||||
let (x,y) = get_point(¢er);
|
||||
let sqr = (&dual * &dual)[SCALAR];
|
||||
let r = sqr.sqrt();
|
||||
return Geometry::Circle(x, y, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,13 +289,12 @@ fn draw_line(context: &CanvasRenderingContext2d, line: &CGA) {
|
||||
context.move_to(canvas_x1, canvas_y1);
|
||||
context.line_to(canvas_x2, canvas_y2);
|
||||
},
|
||||
Geometry::Null => {},
|
||||
}
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
fn draw_line_between(context: &CanvasRenderingContext2d, a: &CGA, b: &CGA) {
|
||||
let line = CGA::e4() ^ a ^ b ^ CGA::e3();
|
||||
let line = CGA::e4() ^ a ^ b;
|
||||
let geometry = get_geometry(&line);
|
||||
context.begin_path();
|
||||
context.set_stroke_style_str(GREEN);
|
||||
@@ -352,20 +348,20 @@ fn _get_hyperbolic_translation(vec: &CGA) -> CGA {
|
||||
t
|
||||
}
|
||||
|
||||
enum CircleIntersection {
|
||||
Two_Points(CGA, CGA),
|
||||
One_Point(CGA),
|
||||
enum _CircleIntersection {
|
||||
TwoPoints(CGA, CGA),
|
||||
OnePoint(CGA),
|
||||
None,
|
||||
}
|
||||
|
||||
/*fn get_circle_intersection(circle_1: &CGA, circle_2: &CGA) -> CircleIntersection {
|
||||
if !circle_intersection(circle_1, circle_2) {
|
||||
if !circle_intersection(;//circle_1, circle_2) {
|
||||
return CircleIntersection::None;
|
||||
}
|
||||
let n = CGA::e4() + CGA::e5();
|
||||
}*/
|
||||
|
||||
fn circle_intersection(circle_1: &CGA, circle_2: &CGA) -> bool {
|
||||
fn _circle_intersection(circle_1: &CGA, circle_2: &CGA) -> bool {
|
||||
let circle_1 = grade_selection(circle_1, 4);
|
||||
let circle_2 = grade_selection(circle_2, 4);
|
||||
let meet = circle_1 & circle_2;
|
||||
@@ -378,7 +374,7 @@ fn circle_intersection(circle_1: &CGA, circle_2: &CGA) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn line_intersection(line_1: &CGA, line_2: &CGA) -> bool {
|
||||
fn _line_intersection(line_1: &CGA, line_2: &CGA) -> bool {
|
||||
let line_1 = grade_selection(line_1, 4);
|
||||
let line_2 = grade_selection(line_2, 4);
|
||||
let meet = line_1 & line_2;
|
||||
@@ -390,8 +386,8 @@ fn line_intersection(line_1: &CGA, line_2: &CGA) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_line_intersection(line_1: &CGA, line_2: &CGA) -> Option<CGA> {
|
||||
if !line_intersection(line_1, line_2) {
|
||||
fn _get_line_intersection(line_1: &CGA, line_2: &CGA) -> Option<CGA> {
|
||||
if !_line_intersection(line_1, line_2) {
|
||||
return None;
|
||||
}
|
||||
let n = CGA::e4() + CGA::e5();
|
||||
@@ -489,7 +485,7 @@ impl Asteroid {
|
||||
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);
|
||||
Asteroid { circle, vel }
|
||||
}
|
||||
@@ -561,6 +557,7 @@ impl Game {
|
||||
self.context.set_stroke_style_str(BLACK);
|
||||
self.context.arc(CENTER_X, CENTER_Y, RADIUS, 0., TWO_PI).unwrap();
|
||||
self.context.stroke();
|
||||
|
||||
draw_line(&self.context, &self.boundary);
|
||||
self.ship.draw(&self.context);
|
||||
for asteroid in &self.asteroids {
|
||||
|
||||
Reference in New Issue
Block a user