Replace circumcenter algorithm with a faster one
This commit is contained in:
parent
a745c63de9
commit
38810f749c
39
src/main.rs
39
src/main.rs
|
@ -1,5 +1,6 @@
|
|||
pub mod util;
|
||||
|
||||
use macroquad::prelude::DMat3;
|
||||
use smallvec::SmallVec;
|
||||
use smallvec::smallvec;
|
||||
use std::collections::HashSet;
|
||||
|
@ -337,25 +338,31 @@ impl Triangle {
|
|||
}
|
||||
|
||||
fn calc_circumcenter(a: DVec2, b: DVec2, c: DVec2) -> (DVec2, f64) {
|
||||
let len_a = b.distance(c);
|
||||
let len_b = c.distance(a);
|
||||
let len_c = a.distance(b);
|
||||
|
||||
let cos_a = (len_b.powf(2.0) + len_c.powf(2.0) - len_a.powf(2.0)) / (2.0 * len_b * len_c );
|
||||
let cos_b = (len_c.powf(2.0) + len_a.powf(2.0) - len_b.powf(2.0)) / (2.0 * len_c * len_a );
|
||||
let mag_a2 = a.powf(2.).dot(DVec2::ONE);
|
||||
let mag_b2 = b.powf(2.).dot(DVec2::ONE);
|
||||
let mag_c2 = c.powf(2.).dot(DVec2::ONE);
|
||||
|
||||
let ang_a = f64::acos(cos_a);
|
||||
let ang_b = f64::acos(cos_b);
|
||||
let ang_c = PI - ang_a - ang_b;
|
||||
|
||||
let sin_2a = f64::sin(2.0 * ang_a);
|
||||
let sin_2b = f64::sin(2.0 * ang_b);
|
||||
let sin_2c = f64::sin(2.0 * ang_c);
|
||||
|
||||
let circumcenter = DVec2::new(
|
||||
(a.x * sin_2a + b.x * sin_2b + c.x * sin_2c) / (sin_2a + sin_2b + sin_2c),
|
||||
(a.y * sin_2a + b.y * sin_2b + c.y * sin_2c) / (sin_2a + sin_2b + sin_2c),
|
||||
let s = DVec2::new(
|
||||
DMat3::from_cols_array(&[
|
||||
mag_a2, a.y, 1.,
|
||||
mag_b2, b.y, 1.,
|
||||
mag_c2, c.y, 1.,
|
||||
]).determinant() * 0.5,
|
||||
DMat3::from_cols_array(&[
|
||||
a.x, mag_a2, 1.,
|
||||
b.x, mag_b2, 1.,
|
||||
c.x, mag_c2, 1.,
|
||||
]).determinant() * 0.5,
|
||||
);
|
||||
|
||||
let little_a = DMat3::from_cols_array(&[
|
||||
a.x, a.y, 1.,
|
||||
b.x, b.y, 1.,
|
||||
c.x, c.y, 1.,
|
||||
]).determinant();
|
||||
|
||||
let circumcenter = s / little_a;
|
||||
let radius = circumcenter.distance(a);
|
||||
|
||||
(circumcenter, radius)
|
||||
|
|
Loading…
Reference in New Issue