Replace circumcenter algorithm with a faster one

This commit is contained in:
Emi Simpson 2021-11-17 23:43:31 -05:00
parent a745c63de9
commit 38810f749c
Signed by: Emi
GPG Key ID: A12F2C2FFDC3D847
1 changed files with 23 additions and 16 deletions

View File

@ -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)