works?
This commit is contained in:
parent
d497f3e96d
commit
9d4c61d7ec
237
src/main.rs
237
src/main.rs
|
|
@ -4,7 +4,7 @@ use flo_draw::{
|
|||
canvas::{Color::Rgba, GraphicsContext, GraphicsPrimitives},
|
||||
create_drawing_window, with_2d_graphics,
|
||||
};
|
||||
use glam::{Mat2, Vec2, vec2};
|
||||
use glam::{FloatExt, Mat2, Vec2, vec2};
|
||||
|
||||
const fn rad(deg: f32) -> f32 {
|
||||
deg * (PI / 180.0)
|
||||
|
|
@ -19,187 +19,114 @@ fn involute_radius_to_t(r: f32) -> f32 {
|
|||
(r * r - 1.).sqrt()
|
||||
}
|
||||
|
||||
fn gear_shape(n: usize) -> Vec<Vec2> {
|
||||
const A: f32 = rad(28.);
|
||||
fn gear_shape_ex(n: usize, inner: f32, outer: f32) -> Vec<Vec2> {
|
||||
const Q: usize = 6;
|
||||
let b = A.cos();
|
||||
|
||||
let offset = involute(involute_radius_to_t(1. / b)).to_angle();
|
||||
let stop_angle = involute_radius_to_t((1.0 + 2.0 / n as f32) / b);
|
||||
let halfangle = PI / n as f32;
|
||||
let ma = Mat2::from_angle(offset - halfangle);
|
||||
let mb = Mat2::from_diagonal(vec2(1., -1.)) * ma;
|
||||
const A: f32 = rad(28.);
|
||||
let base = A.cos();
|
||||
|
||||
let mut ret = Vec::with_capacity(2 * n * Q);
|
||||
let base_to_pitch_angle = involute(involute_radius_to_t(1. / base)).to_angle();
|
||||
|
||||
let tooth_angle = 2.0 * PI / n as f32;
|
||||
println!("{n}: {base}, {inner}, {outer}");
|
||||
let t1 = involute_radius_to_t((inner / base).max(1.));
|
||||
let t2 = involute_radius_to_t(outer / base);
|
||||
println!("{t1}-{t2}");
|
||||
println!("{base_to_pitch_angle}, {}", tooth_angle / 4.);
|
||||
|
||||
let mut side = [Vec2::ZERO; Q + 2];
|
||||
side[0] = vec2(inner, 0.0);
|
||||
for k in 0..=Q {
|
||||
let t01 = k as f32 / Q as f32;
|
||||
let t = f32::lerp(t1, t2, t01);
|
||||
side[k + 1] = base * involute(t);
|
||||
}
|
||||
|
||||
let m = Mat2::from_angle(-(tooth_angle / 4.0 + base_to_pitch_angle));
|
||||
for p in &mut side {
|
||||
*p = m * *p;
|
||||
}
|
||||
if base_to_pitch_angle > tooth_angle / 4.0 {
|
||||
side[0] = Mat2::from_angle(-(tooth_angle / 2.0)) * vec2(inner, 0.0);
|
||||
}
|
||||
|
||||
let mut ret = Vec::with_capacity(2 * n * (Q + 2));
|
||||
for i in 0..n {
|
||||
let m = Mat2::from_angle(i as f32 * 2. * halfangle);
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let p = b * m * ma * involute(stop_angle * t);
|
||||
ret.push(p);
|
||||
let m = Mat2::from_angle(i as f32 * tooth_angle);
|
||||
for p in side {
|
||||
ret.push(m * p);
|
||||
}
|
||||
for k in 0..=Q {
|
||||
let t = 1. - k as f32 / Q as f32;
|
||||
let p = b * m * mb * involute(stop_angle * t);
|
||||
ret.push(p);
|
||||
for p in side.iter().rev() {
|
||||
ret.push(m * vec2(p.x, -p.y));
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn gear_shape_std(n: usize, low: f32, high: f32) -> Vec<Vec2> {
|
||||
let unit = 1.0 / n as f32;
|
||||
return gear_shape_ex(n, 1.0 - low * unit, 1.0 + high * unit);
|
||||
}
|
||||
|
||||
fn gear_shape(n: usize) -> Vec<Vec2> {
|
||||
return gear_shape_std(n, 2.2, 2.0);
|
||||
}
|
||||
|
||||
fn gear_shape_outer(n: usize) -> Vec<Vec2> {
|
||||
return gear_shape_std(n, 2.0, 2.2);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let g24 = gear_shape(24);
|
||||
let g36 = gear_shape(36);
|
||||
const R_SCALE: f32 = 0.5;
|
||||
const N_TEETH_SUN: usize = 36;
|
||||
const N_TEETH_SAT: usize = 24;
|
||||
const N_TEETH_SKY: usize = N_TEETH_SUN + 2 * N_TEETH_SAT;
|
||||
const N_SAT: usize = 3;
|
||||
const R_SUN: f32 = R_SCALE * N_TEETH_SUN as f32;
|
||||
const R_SAT: f32 = R_SCALE * N_TEETH_SAT as f32;
|
||||
const OFF_SAT: f32 = R_SUN + R_SAT;
|
||||
const R_SKY: f32 = R_SCALE * N_TEETH_SKY as f32;
|
||||
|
||||
with_2d_graphics(|| {
|
||||
let sun = gear_shape(N_TEETH_SUN);
|
||||
let sat = gear_shape(N_TEETH_SAT);
|
||||
let crown = gear_shape_outer(N_TEETH_SKY);
|
||||
|
||||
let canvas = create_drawing_window("Canvas window");
|
||||
canvas.draw(|gc| {
|
||||
gc.clear_canvas(Rgba(0.1, 0.1, 0.1, 1.0));
|
||||
|
||||
gc.canvas_height(50.0);
|
||||
gc.line_width(0.5);
|
||||
|
||||
const N1: usize = 20;
|
||||
const N2: usize = 50;
|
||||
const R1: f32 = 20.;
|
||||
const R2: f32 = 50.;
|
||||
const A: f32 = rad(28.);
|
||||
|
||||
let b = A.cos();
|
||||
let b1 = b * R1;
|
||||
let b2 = b * R2;
|
||||
let offset = involute_radius_to_t(1. / b);
|
||||
let offset = involute(offset).to_angle();
|
||||
gc.canvas_height(100.0);
|
||||
gc.line_width(0.25);
|
||||
|
||||
gc.new_path();
|
||||
gc.stroke_color(Rgba(0.3, 0.3, 0.3, 1.0));
|
||||
gc.circle(-R1, 0., R1);
|
||||
gc.circle(R2, 0., R2);
|
||||
gc.circle(-R2, 0., R2);
|
||||
gc.stroke();
|
||||
|
||||
gc.new_path();
|
||||
gc.stroke_color(Rgba(0.1, 0.1, 0.8, 1.0));
|
||||
gc.circle(-R1, 0., b1);
|
||||
gc.circle(R2, 0., b2);
|
||||
gc.circle(-R2, 0., b2);
|
||||
gc.stroke();
|
||||
|
||||
// let pitch_radius = R1;
|
||||
// let base_radius = b1;
|
||||
// let number_of_teeth = N1;
|
||||
// let addendum = 2.0 * pitch_radius / number_of_teeth as f32;
|
||||
// let clearance = 0.0;
|
||||
// let dedendum = addendum + clearance;
|
||||
|
||||
const Q: usize = 12;
|
||||
|
||||
let stop_angle = involute_radius_to_t((1.0 + 2.0 / N1 as f32) / b);
|
||||
let halfangle = PI / N1 as f32;
|
||||
let ma = Mat2::from_angle(offset - halfangle);
|
||||
let mb = Mat2::from_diagonal(vec2(1., -1.)) * ma;
|
||||
gc.new_path();
|
||||
for i in 0..N1 {
|
||||
let m = Mat2::from_angle(i as f32 / N1 as f32 * 2. * PI);
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let p = b1 * m * ma * involute(stop_angle * t) - vec2(R1, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
for k in 0..=Q {
|
||||
let t = 1. - k as f32 / Q as f32;
|
||||
let p = b1 * m * mb * involute(stop_angle * t) - vec2(R1, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
for pt in sun {
|
||||
let pt = R_SUN * pt;
|
||||
gc.line_to(pt.x, pt.y);
|
||||
}
|
||||
gc.close_path();
|
||||
gc.stroke_color(Rgba(0.1, 0.8, 0.1, 1.0));
|
||||
gc.stroke_color(Rgba(0.8, 0.7, 0.1, 1.0));
|
||||
gc.stroke();
|
||||
|
||||
let stop_angle = involute_radius_to_t((1.0 + 2.0 / N2 as f32) / b);
|
||||
let halfangle = PI / N2 as f32;
|
||||
let ma = Mat2::from_angle(offset - halfangle);
|
||||
let mb = Mat2::from_diagonal(vec2(1., -1.)) * ma;
|
||||
for k in 0..N_SAT {
|
||||
let m = Mat2::from_angle(k as f32 / N_SAT as f32 * 2. * PI);
|
||||
gc.new_path();
|
||||
for pt in &sat {
|
||||
let pt = m * vec2(OFF_SAT, 0.) + R_SAT * pt;
|
||||
gc.line_to(pt.x, pt.y);
|
||||
}
|
||||
gc.close_path();
|
||||
gc.stroke_color(Rgba(0.1, 0.8, 0.1, 1.0));
|
||||
gc.stroke();
|
||||
}
|
||||
|
||||
gc.new_path();
|
||||
for i in 0..N2 {
|
||||
let m = Mat2::from_angle((i as f32 - 0.5) / N2 as f32 * 2. * PI);
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let p = b2 * m * ma * involute(stop_angle * t) + vec2(R2, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
for k in 0..=Q {
|
||||
let t = 1. - k as f32 / Q as f32;
|
||||
let p = b2 * m * mb * involute(stop_angle * t) + vec2(R2, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
for pt in crown {
|
||||
let pt = R_SKY * pt;
|
||||
gc.line_to(pt.x, pt.y);
|
||||
}
|
||||
gc.close_path();
|
||||
gc.stroke_color(Rgba(0.1, 0.8, 0.1, 1.0));
|
||||
gc.stroke();
|
||||
|
||||
gc.new_path();
|
||||
gc.stroke_color(Rgba(0.1, 0.4, 0.8, 1.0));
|
||||
gc.move_to(-5., 0.);
|
||||
gc.line_to(5., 0.);
|
||||
gc.stroke();
|
||||
|
||||
return;
|
||||
|
||||
let m = Mat2::IDENTITY; // Mat2::from_angle(-offset);
|
||||
|
||||
gc.new_path();
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let p = vec2(R2, 0.) - b2 * m * involute(t);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
gc.stroke_color(Rgba(0.1, 0.8, 0.1, 1.0));
|
||||
gc.stroke();
|
||||
|
||||
gc.new_path();
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let m1 = Mat2::from_angle(A - t);
|
||||
let m2 = Mat2::from_angle((A - t) * R1 / R2);
|
||||
let p = b1 * m1 * m * involute(t) - vec2(R1, 0.);
|
||||
let p = m2 * (p - vec2(R2, 0.)) + vec2(R2, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
gc.stroke_color(Rgba(0.8, 0.8, 0.1, 1.0));
|
||||
gc.stroke();
|
||||
|
||||
gc.new_path();
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let m1 = Mat2::from_angle(A - t);
|
||||
let m2 = Mat2::from_angle((t - A) * R1 / R2);
|
||||
let p = b1 * m1 * m * involute(t) - vec2(R1, 0.);
|
||||
let p = m2 * (p + vec2(R2, 0.)) - vec2(R2, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
gc.stroke_color(Rgba(0.8, 0.1, 0.1, 1.0));
|
||||
gc.stroke();
|
||||
|
||||
gc.new_path();
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let m1 = Mat2::from_angle(A - t);
|
||||
let m2 = Mat2::from_angle(t - A);
|
||||
let p = b2 * m1 * m * involute(t) - vec2(R2, 0.);
|
||||
let p = m2 * (p + vec2(R2, 0.)) - vec2(R2, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
gc.stroke_color(Rgba(0.8, 0.4, 0.1, 1.0));
|
||||
gc.stroke();
|
||||
|
||||
gc.new_path();
|
||||
for k in 0..=Q {
|
||||
let t = k as f32 / Q as f32;
|
||||
let p = b2 * m * involute(t) - vec2(R2, 0.);
|
||||
gc.line_to(p.x, p.y);
|
||||
}
|
||||
gc.stroke_color(Rgba(0.1, 0.8, 0.8, 0.5));
|
||||
gc.stroke();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user