From 38810f749c3443fcd685a077f57b4870ac15c868 Mon Sep 17 00:00:00 2001 From: Emi Simpson Date: Wed, 17 Nov 2021 23:43:31 -0500 Subject: [PATCH] Replace circumcenter algorithm with a faster one --- src/main.rs | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index c66e0ba..8c9aac8 100644 --- a/src/main.rs +++ b/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)