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