cut involute gear teeth
This commit is contained in:
parent
4324336cf0
commit
51a9c1345d
161
src/main.rs
161
src/main.rs
|
|
@ -1,4 +1,4 @@
|
||||||
use std::f32::consts::PI;
|
use std::{f32::consts::PI, time::Duration};
|
||||||
|
|
||||||
use flo_draw::{
|
use flo_draw::{
|
||||||
canvas::{Color::Rgba, GraphicsContext, GraphicsPrimitives, Transform2D},
|
canvas::{Color::Rgba, GraphicsContext, GraphicsPrimitives, Transform2D},
|
||||||
|
|
@ -216,38 +216,147 @@ fn cut_crown(gc: &mut impl GraphicsContext, n_teeth_crown: u32, n_teeth_gear: u3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(gc: &mut impl GraphicsContext) {
|
fn cutter_y_at_x(x: f32) -> f32 {
|
||||||
gc.clear_canvas(Rgba(0.1, 0.1, 0.1, 1.0));
|
let x = (x / PITCH).fract_gl() * PITCH;
|
||||||
|
let a = DEDENDUM * vec2(PRESSURE_ANGLE.tan(), 1.0);
|
||||||
gc.canvas_height(20.0);
|
let d = ADDENDUM * vec2(PRESSURE_ANGLE.tan(), -1.0);
|
||||||
gc.line_width(0.05);
|
let slope = 1.0 / PRESSURE_ANGLE.tan();
|
||||||
|
if x < d.x {
|
||||||
gc.stroke_color(Rgba(1.0, 0.1, 0.1, 0.1));
|
return -x * slope;
|
||||||
// cut_involute(gc, 24);
|
}
|
||||||
|
if x <= 0.5 * PITCH - d.x {
|
||||||
gc.stroke_color(Rgba(0.1, 1.0, 0.1, 0.1));
|
return d.y;
|
||||||
cut_crown(gc, 36, 24);
|
}
|
||||||
|
if x <= 0.5 * PITCH + a.x {
|
||||||
|
return (x - 0.5 * PITCH) * slope;
|
||||||
|
}
|
||||||
|
if x <= PITCH - a.x {
|
||||||
|
return a.y;
|
||||||
|
}
|
||||||
|
return (PITCH - x) * slope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FPS: f32 = 60.0;
|
||||||
|
const TPS: f32 = 1.0;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
with_2d_graphics(|| {
|
with_2d_graphics(|| {
|
||||||
let title = "Gear shape test";
|
let title = "Gear shape test";
|
||||||
if cfg!(events) {
|
use futures::StreamExt;
|
||||||
use futures::StreamExt;
|
use std::task::{Context, Poll, Waker};
|
||||||
use std::task::{Context, Poll, Waker};
|
|
||||||
|
|
||||||
let (canvas, mut events) = create_drawing_window_with_events(title);
|
let (canvas, mut events) = create_drawing_window_with_events(title);
|
||||||
'main: loop {
|
let mut t = 0.0;
|
||||||
while let Poll::Ready(event) =
|
|
||||||
events.poll_next_unpin(&mut Context::from_waker(Waker::noop()))
|
let n_rack_teeth = 10;
|
||||||
{
|
|
||||||
let Some(_event) = event else { break 'main };
|
let n_teeth = 36;
|
||||||
}
|
let n_teeth_sample = n_teeth;
|
||||||
canvas.draw(draw);
|
let r_pitch = 0.5 * n_teeth as f32;
|
||||||
|
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];
|
||||||
|
'main: loop {
|
||||||
|
while let Poll::Ready(event) =
|
||||||
|
events.poll_next_unpin(&mut Context::from_waker(Waker::noop()))
|
||||||
|
{
|
||||||
|
let Some(_event) = event else { break 'main };
|
||||||
}
|
}
|
||||||
} else {
|
canvas.draw(|gc| {
|
||||||
let canvas = create_drawing_window(title);
|
gc.clear_canvas(Rgba(0.1, 0.1, 0.1, 1.0));
|
||||||
canvas.draw(draw);
|
|
||||||
|
gc.canvas_height(20.0);
|
||||||
|
gc.line_width(0.05);
|
||||||
|
|
||||||
|
gc.stroke_color(Rgba(1.0, 1.0, 1.0, 0.1));
|
||||||
|
gc.move_to(-20.0, 0.0);
|
||||||
|
gc.line_to(20.0, 0.0);
|
||||||
|
gc.move_to(0.0, -20.0);
|
||||||
|
gc.line_to(0.0, 20.0);
|
||||||
|
gc.stroke();
|
||||||
|
|
||||||
|
let gear_offset = t * TPS - (n_teeth_sample as f32 + 5.0);
|
||||||
|
let rack_offset = (t * TPS).fract_gl();
|
||||||
|
|
||||||
|
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;
|
||||||
|
let (s, c) = angle.sin_cos();
|
||||||
|
vec2(s * r, r_pitch - c * r)
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
if cut_y < xy.y {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*r -= 0.01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
line(gc, pts);
|
||||||
|
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);
|
||||||
|
gc.stroke_color(Rgba(0.1, 1.0, 0.1, 0.4));
|
||||||
|
gc.stroke();
|
||||||
|
});
|
||||||
|
|
||||||
|
std::thread::sleep(Duration::from_secs_f32(1.0 / FPS));
|
||||||
|
t += 1.0 / FPS;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn line(gc: &mut impl GraphicsContext, pts: impl IntoIterator<Item = Vec2>) {
|
||||||
|
let mut pts = pts.into_iter();
|
||||||
|
let Some(pt) = pts.next() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
gc.move_to(pt.x, pt.y);
|
||||||
|
for pt in pts {
|
||||||
|
gc.line_to(pt.x, pt.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user