additional track fields + simplified arc helper

This commit is contained in:
nquidox 2026-04-17 16:24:53 +03:00
parent 5ba555b062
commit a1180ea769
2 changed files with 29 additions and 14 deletions

View file

@ -27,7 +27,10 @@ pub enum PathSegment {
#[derive(Resource)] #[derive(Resource)]
pub struct PrecalculatedTrack{ pub struct PrecalculatedTrack{
pub segments: Vec<PTSegment> pub segments: Vec<PTSegment>,
pub min_spawn_gap: f32, //нормализован
pub total_length: f32,
pub speed_norm: f32,
} }
#[derive(Debug)] #[derive(Debug)]
@ -41,6 +44,7 @@ pub struct PTSegment {
pub radius: f32, pub radius: f32,
pub start_angle: f32, pub start_angle: f32,
pub sweep_sign: f32, pub sweep_sign: f32,
pub length: f32,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]

View file

@ -1,7 +1,6 @@
use crate::FACTOR; use crate::FACTOR;
use crate::states::linear::*; use crate::states::linear::*;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::reflect::List;
use std::f32::consts::FRAC_PI_2; use std::f32::consts::FRAC_PI_2;
pub fn setup_linear_track() -> Track { pub fn setup_linear_track() -> Track {
@ -69,7 +68,12 @@ pub fn setup_linear_track() -> Track {
} }
pub fn precalculate_track(track: &Track) -> PrecalculatedTrack { pub fn precalculate_track(track: &Track) -> PrecalculatedTrack {
let mut pt = PrecalculatedTrack { segments: vec![] }; let mut pt = PrecalculatedTrack {
segments: vec![],
min_spawn_gap: 0.0,
total_length: 0.0,
speed_norm: 0.0,
};
let mut cumulative_length: Vec<f32> = vec![0.0]; let mut cumulative_length: Vec<f32> = vec![0.0];
let mut current_pos = track.start_point; let mut current_pos = track.start_point;
@ -90,6 +94,7 @@ pub fn precalculate_track(track: &Track) -> PrecalculatedTrack {
radius: 0.0, radius: 0.0,
start_angle: 0.0, start_angle: 0.0,
sweep_sign: 0.0, sweep_sign: 0.0,
length: *length,
}; };
pt.segments.push(calc_seg); pt.segments.push(calc_seg);
@ -102,6 +107,7 @@ pub fn precalculate_track(track: &Track) -> PrecalculatedTrack {
PathSegment::Turn { radius, left } => { PathSegment::Turn { radius, left } => {
let arc = helper_arc_calculator(current_pos, current_dir, *left, *radius); let arc = helper_arc_calculator(current_pos, current_dir, *left, *radius);
let arc_len = FRAC_PI_2 * radius;
let calc_seg = PTSegment { let calc_seg = PTSegment {
t_start: 0.0, t_start: 0.0,
@ -113,14 +119,14 @@ pub fn precalculate_track(track: &Track) -> PrecalculatedTrack {
radius: *radius, radius: *radius,
start_angle: arc.start_angle, start_angle: arc.start_angle,
sweep_sign: arc.sweep_sign, sweep_sign: arc.sweep_sign,
length: arc_len,
}; };
pt.segments.push(calc_seg); pt.segments.push(calc_seg);
// сдвигаем позицию для следующего сегмента // сдвигаем позицию для следующего сегмента
current_pos = arc.end_pos; current_pos = arc.end_pos;
current_dir = arc.normal; current_dir = arc.normal;
// накапливаем длину // накапливаем длину
cumulative_length cumulative_length.push(cumulative_length[cumulative_length.len() - 1] + arc_len);
.push(cumulative_length[cumulative_length.len() - 1] + (FRAC_PI_2 * radius));
} }
} }
} }
@ -141,30 +147,35 @@ pub fn precalculate_track(track: &Track) -> PrecalculatedTrack {
println!("{:?}", seg); println!("{:?}", seg);
} }
// считаем нормализованный зазор на треке, когда будет доступен спавн шарика
// pt.min_spawn_gap = STEP / total_length;
pt.min_spawn_gap = STEP / total_length;
pt.total_length = total_length;
pt.speed_norm = STEP / total_length; // нормализованное смещение для скорости в пикселях
println!(
"Нормализованное значение размера шарика: {}, уе: {}, общая длина: {}",
pt.min_spawn_gap, STEP, total_length
);
pt pt
} }
pub fn helper_arc_calculator(pos: Vec2, dir: Vec2, turn_to: bool, radius: f32) -> ArcCalculation { pub fn helper_arc_calculator(pos: Vec2, dir: Vec2, turn_to: bool, radius: f32) -> ArcCalculation {
let (normal, sign): (Vec2, f32) = if turn_to { let (normal, sign): (Vec2, f32) = if turn_to {
(Vec2::new(-dir.y, dir.x), -1.0) (Vec2::new(-dir.y, dir.x), 1.0)
} else { } else {
(Vec2::new(dir.y, -dir.x), 1.0) (Vec2::new(dir.y, -dir.x), -1.0)
}; };
let center = pos + normal * radius; let center = pos + normal * radius;
let start_vec = pos - center; let start_vec = pos - center;
let initial_vec = if turn_to { let angle = start_vec.to_angle();
-start_vec.perp()
} else {
-start_vec
};
let angle = initial_vec.to_angle();
ArcCalculation { ArcCalculation {
normal, normal,
center, center,
start_angle: angle, start_angle: angle,
sweep_sign: sign, sweep_sign: sign,
end_pos: center + normal.perp() * radius * sign, end_pos: center - normal.perp() * radius * sign,
} }
} }