improved slider point interpolation
This commit is contained in:
+7
-6
@@ -5,7 +5,8 @@
|
||||
|
||||
use crate::{math_util, parse::Pos2};
|
||||
|
||||
const SLIDER_QUALITY: f32 = 50.0;
|
||||
const BEZIER_TOLERANCE: f32 = 0.25;
|
||||
const CATMULL_DETAIL: f32 = 50.0;
|
||||
|
||||
pub(crate) enum Points {
|
||||
Single(Pos2),
|
||||
@@ -57,7 +58,7 @@ impl Curve {
|
||||
}
|
||||
|
||||
fn _bezier(result: &mut Vec<Pos2>, points: &[Pos2]) {
|
||||
let step = (0.25 / SLIDER_QUALITY / points.len() as f32).max(0.01);
|
||||
let step = (BEZIER_TOLERANCE / points.len() as f32).max(0.01);
|
||||
let mut i = 0.0;
|
||||
let n = points.len() as i32 - 1;
|
||||
|
||||
@@ -81,7 +82,7 @@ impl Curve {
|
||||
let order = points.len();
|
||||
|
||||
let mut resulting_points =
|
||||
Vec::with_capacity(((order - 1) as f32 * SLIDER_QUALITY * 2.0) as usize);
|
||||
Vec::with_capacity(((order - 1) as f32 * CATMULL_DETAIL * 2.0) as usize);
|
||||
|
||||
for i in 0..order - 1 {
|
||||
let v1 = points[i.saturating_sub(1)];
|
||||
@@ -101,14 +102,14 @@ impl Curve {
|
||||
|
||||
let mut c = 0.0;
|
||||
|
||||
while c < SLIDER_QUALITY {
|
||||
resulting_points.push(Self::catmull_point(v1, v2, v3, v4, c / SLIDER_QUALITY));
|
||||
while c < CATMULL_DETAIL {
|
||||
resulting_points.push(Self::catmull_point(v1, v2, v3, v4, c / CATMULL_DETAIL));
|
||||
resulting_points.push(Self::catmull_point(
|
||||
v1,
|
||||
v2,
|
||||
v3,
|
||||
v4,
|
||||
(c + 1.0) / SLIDER_QUALITY,
|
||||
(c + 1.0) / CATMULL_DETAIL,
|
||||
));
|
||||
|
||||
c += 1.0;
|
||||
|
||||
+3
-18
@@ -41,11 +41,6 @@ pub(crate) fn point_on_line(p1: Pos2, p2: Pos2, len: f32) -> Pos2 {
|
||||
(p1 * n + p2 * len) / full_len
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn angle_from_points(p0: Pos2, p1: Pos2) -> f32 {
|
||||
(p1.y - p0.y).atan2(p1.x - p0.x)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn distance_from_points(arr: &[Pos2]) -> f32 {
|
||||
arr.iter()
|
||||
@@ -55,14 +50,6 @@ pub(crate) fn distance_from_points(arr: &[Pos2]) -> f32 {
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn cart_from_pol(r: f32, t: f32) -> Pos2 {
|
||||
Pos2 {
|
||||
x: r * t.cos(),
|
||||
y: r * t.sin(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn point_at_distance(array: &[Pos2], distance: f32) -> Pos2 {
|
||||
if array.len() < 2 {
|
||||
return Pos2 { x: 0.0, y: 0.0 };
|
||||
@@ -88,14 +75,12 @@ pub(crate) fn point_at_distance(array: &[Pos2], distance: f32) -> Pos2 {
|
||||
}
|
||||
|
||||
current_distance -= new_distance;
|
||||
let init_dist = distance - current_distance;
|
||||
|
||||
if (distance - current_distance).abs() <= f32::EPSILON {
|
||||
if init_dist.abs() <= f32::EPSILON {
|
||||
array[i]
|
||||
} else {
|
||||
let angle = angle_from_points(array[i], array[i + 1]);
|
||||
let cart = cart_from_pol(distance - current_distance, angle);
|
||||
|
||||
array[i] + cart * ((array[i].x <= array[i + 1].x) as i8 * 2 - 1) as f32
|
||||
array[i] + (array[i + 1] - array[i]) * (init_dist / new_distance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user