diff --git a/src/lib.rs b/src/lib.rs index e4831fa..64f103e 100644 --- a/src/lib.rs +++ b/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 { - if !line_intersection(line_1, line_2) { +fn _get_line_intersection(line_1: &CGA, line_2: &CGA) -> Option { + 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 {