From 52baff44c3350fffeaff0dc7dc9ad8682a4addb4 Mon Sep 17 00:00:00 2001 From: numzero Date: Thu, 8 Oct 2026 20:03:53 +0300 Subject: [PATCH] unify shaping code --- src/main.rs | 90 ++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/src/main.rs b/src/main.rs index be95e0e..3051836 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,26 +13,32 @@ const fn rad(deg: f32) -> f32 { const ADDENDUM: f32 = 1.00; const DEDENDUM: f32 = 1.25; const PRESSURE_ANGLE: f32 = rad(20.0); -const PITCH: f32 = PI; -fn cutter_y_at_x(x: f32) -> f32 { - let x = (x / PITCH).fract_gl() * PITCH; - let a = DEDENDUM * vec2(PRESSURE_ANGLE.tan(), 1.0); - let d = ADDENDUM * vec2(PRESSURE_ANGLE.tan(), -1.0); - let slope = 1.0 / PRESSURE_ANGLE.tan(); +#[derive(Debug, Clone, Copy)] +struct Profile { + addemdum: f32, + dedendum: f32, + pressure_angle: f32, +} + +fn rack_shape(x: f32, profile: &Profile) -> f32 { + let x = (x / PI).fract_gl() * PI; + let a = profile.addemdum * vec2(profile.pressure_angle.tan(), 1.0); + let d = profile.dedendum * vec2(profile.pressure_angle.tan(), -1.0); + let slope = 1.0 / profile.pressure_angle.tan(); if x < d.x { return -x * slope; } - if x <= 0.5 * PITCH - d.x { + if x <= 0.5 * PI - d.x { return d.y; } - if x <= 0.5 * PITCH + a.x { - return (x - 0.5 * PITCH) * slope; + if x <= 0.5 * PI + a.x { + return (x - 0.5 * PI) * slope; } - if x <= PITCH - a.x { + if x <= PI - a.x { return a.y; } - return (PITCH - x) * slope; + return (PI - x) * slope; } const FPS: f32 = 60.0; @@ -52,6 +58,18 @@ fn main() { let n_teeth = 36; let n_teeth_sample = n_teeth; let r_pitch = 0.5 * n_teeth as f32; + + let gear_profile = Profile { + addemdum: ADDENDUM, + dedendum: DEDENDUM, + pressure_angle: PRESSURE_ANGLE, + }; + let cutter_profile = Profile { + addemdum: gear_profile.dedendum, + dedendum: gear_profile.addemdum, + pressure_angle: gear_profile.pressure_angle, + }; + let n_points_per_tooth = 100; let n_points = n_points_per_tooth * n_teeth_sample; let mut shape = vec![r_pitch + ADDENDUM; n_points]; @@ -77,6 +95,9 @@ fn main() { let gear_offset = t * TPS - (n_teeth_sample as f32 + 5.0); let rack_offset = (t * TPS).fract_gl(); + let rack_y_at_x = |x, profile| rack_shape(x - rack_offset * PI, profile); + let cutter_y_at_x = |x| rack_y_at_x(x, &cutter_profile); + let kr_to_xy = |k, r: f32| { let u = k as f32 / n_points_per_tooth as f32; let angle = 2.0 * PI * (gear_offset + u) / n_teeth as f32; @@ -87,7 +108,7 @@ fn main() { for (k, r) in shape.iter_mut().enumerate() { loop { let xy = kr_to_xy(k, *r); - let cut_y = cutter_y_at_x(xy.x - rack_offset * PITCH); + let cut_y = cutter_y_at_x(xy.x); if cut_y < xy.y { break; } @@ -95,50 +116,27 @@ fn main() { } } - #[cfg(false)] - { - line( - gc, - shape.iter().enumerate().map(|(k, r)| { - let xy = kr_to_xy(k, *r); - let cut_y = cutter_y_at_x(xy.x - rack_offset * PITCH); - vec2(xy.x, cut_y) - }), - ); - gc.stroke_color(Rgba(1.0, 1.0, 0.1, 0.4)); - gc.stroke(); - } - line(gc, shape.iter().enumerate().map(|(k, r)| kr_to_xy(k, *r))); gc.close_path(); gc.stroke_color(Rgba(0.1, 0.6, 1.0, 0.4)); gc.stroke(); - let mut pts = Vec::new(); + let mut pts_rack = Vec::new(); + let mut pts_cutter = Vec::new(); for tooth in -n_rack_teeth..=n_rack_teeth { - let x = (tooth as f32 + rack_offset) * PITCH; - let a = DEDENDUM * vec2(PRESSURE_ANGLE.tan(), 1.0); - let d = ADDENDUM * vec2(PRESSURE_ANGLE.tan(), -1.0); - pts.push(vec2(x - 0.5 * PITCH - d.x, d.y)); - pts.push(vec2(x - 0.5 * PITCH + a.x, a.y)); - pts.push(vec2(x - a.x, a.y)); - pts.push(vec2(x + d.x, d.y)); + for k in 0..n_points_per_tooth { + let x = (tooth as f32 + k as f32 / n_points_per_tooth as f32 + rack_offset) + * PI; + pts_rack.push(vec2(x, rack_y_at_x(x, &gear_profile))); + pts_cutter.push(vec2(x, cutter_y_at_x(x))); + } } - line(gc, pts); + + line(gc, pts_cutter); gc.stroke_color(Rgba(1.0, 0.1, 0.1, 0.4)); gc.stroke(); - let mut pts = Vec::new(); - for tooth in -n_rack_teeth..=n_rack_teeth { - let x = (tooth as f32 + rack_offset) * PITCH; - let a = ADDENDUM * vec2(PRESSURE_ANGLE.tan(), 1.0); - let d = DEDENDUM * vec2(PRESSURE_ANGLE.tan(), -1.0); - pts.push(vec2(x - 0.5 * PITCH - d.x, d.y)); - pts.push(vec2(x - 0.5 * PITCH + a.x, a.y)); - pts.push(vec2(x - a.x, a.y)); - pts.push(vec2(x + d.x, d.y)); - } - line(gc, pts); + line(gc, pts_rack); gc.stroke_color(Rgba(0.1, 1.0, 0.1, 0.4)); gc.stroke(); });