Able to draw lines of ship between the three vertices.
This commit is contained in:
72
src/lib.rs
72
src/lib.rs
@@ -41,8 +41,8 @@ const RADIUS: f64 = 250.;
|
||||
const BACKGROUND: &str = "#ffffff";
|
||||
const BLACK: &str = "#000000";
|
||||
const RED: &str = "#ff0000";
|
||||
const _GREEN: &str = "#00ff00";
|
||||
const _BLUE: &str = "#0000ff";
|
||||
const GREEN: &str = "#00ff00";
|
||||
const BLUE: &str = "#0000ff";
|
||||
|
||||
const SCALAR: usize = 0;
|
||||
const E1: usize = 1;
|
||||
@@ -130,6 +130,15 @@ fn draw_point(context: &CanvasRenderingContext2d, point: &CGA) {
|
||||
context.set_fill_style_str(RED);
|
||||
context.arc(x, y, 2., 0., TWO_PI).unwrap();
|
||||
context.fill();
|
||||
|
||||
let (x,y) = get_point(point);
|
||||
let (x,y) = point_to_screen_space(x,y);
|
||||
|
||||
context.begin_path();
|
||||
context.set_fill_style_str(BLUE);
|
||||
context.arc(x, y, 2., 0., TWO_PI).unwrap();
|
||||
context.fill();
|
||||
|
||||
}
|
||||
|
||||
//TODO Integrate into get geometry
|
||||
@@ -161,6 +170,14 @@ fn get_hyperbolic_point(point: &CGA) -> (f64, f64) {
|
||||
(r*x,r*y)
|
||||
}
|
||||
|
||||
fn get_point(point: &CGA) -> (f64, f64) {
|
||||
let x = point[E1];
|
||||
let y = point[E2];
|
||||
let n = CGA::e4()+CGA::e5();
|
||||
let norm = -(point | &n)[SCALAR];
|
||||
(x/norm, y/norm)
|
||||
}
|
||||
|
||||
fn get_geometry(circle: &CGA) -> Geometry {
|
||||
//Naively assume we are given a valid line/circle
|
||||
let n_bar = CGA::e4() - CGA::e5();
|
||||
@@ -193,7 +210,7 @@ fn get_geometry(circle: &CGA) -> Geometry {
|
||||
|
||||
fn draw_line(context: &CanvasRenderingContext2d, line: &CGA) {
|
||||
context.begin_path();
|
||||
context.set_stroke_style_str(_GREEN);
|
||||
context.set_stroke_style_str(GREEN);
|
||||
|
||||
let geometry = get_geometry(line);
|
||||
match geometry {
|
||||
@@ -216,6 +233,52 @@ fn draw_line(context: &CanvasRenderingContext2d, line: &CGA) {
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
fn draw_line_between(context: &CanvasRenderingContext2d, a: &CGA, b: &CGA) {
|
||||
let line = CGA::e4() ^ a ^ b ^ CGA::e3();
|
||||
let geometry = get_geometry(&line);
|
||||
context.begin_path();
|
||||
context.set_stroke_style_str(GREEN);
|
||||
match geometry {
|
||||
Geometry::Circle(x,y,r) => {
|
||||
let (a_x, a_y) = get_point(a);
|
||||
let (b_x, b_y) = get_point(b);
|
||||
let mut theta_a = (a_y-y).atan2(a_x-x);
|
||||
let mut theta_b = (b_y-y).atan2(b_x-x);
|
||||
if theta_a < 0. {
|
||||
theta_a += TWO_PI;
|
||||
}
|
||||
if theta_b < 0. {
|
||||
theta_b += TWO_PI;
|
||||
}
|
||||
let mut delta = theta_b - theta_a;
|
||||
if delta < -PI {
|
||||
delta += TWO_PI;
|
||||
} else if delta > PI {
|
||||
delta -= TWO_PI;
|
||||
}
|
||||
let (x,y) = point_to_screen_space(x,y);
|
||||
let r = RADIUS*r;
|
||||
if delta < 0. {
|
||||
if theta_a + delta < 0. {
|
||||
context.arc(x, y, r, 0., theta_a).unwrap();
|
||||
context.arc(x, y, r, theta_a + delta + TWO_PI, TWO_PI).unwrap();
|
||||
} else {
|
||||
context.arc(x, y, r, theta_a + delta, theta_a).unwrap();
|
||||
}
|
||||
} else {
|
||||
if theta_a + delta > TWO_PI {
|
||||
context.arc(x, y, r, theta_a, TWO_PI).unwrap();
|
||||
context.arc(x, y, r, 0., theta_a + delta - TWO_PI).unwrap();
|
||||
} else {
|
||||
context.arc(x, y, r, theta_a, theta_a + delta).unwrap();
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
fn _get_hyperbolic_translation(vec: &CGA) -> CGA {
|
||||
let vec_sqr = (vec * vec)[SCALAR];
|
||||
if vec_sqr >= 1. {
|
||||
@@ -332,6 +395,9 @@ impl Game {
|
||||
draw_point(&self.context, &p0);
|
||||
draw_point(&self.context, &p1);
|
||||
draw_point(&self.context, &p2);
|
||||
draw_line_between(&self.context, &p0, &p1);
|
||||
draw_line_between(&self.context, &p1, &p2);
|
||||
draw_line_between(&self.context, &p2, &p0);
|
||||
|
||||
//Construct and draw line pointing straight ahead, to help orient the player.
|
||||
let com_p = com * gen_hyperbolic_point(&CGA::zero()) * com.Reverse();
|
||||
|
||||
Reference in New Issue
Block a user