Skip to content

Commit 054f61d

Browse files
committed
cargo fmt
1 parent d1ecd3f commit 054f61d

File tree

1 file changed

+95
-95
lines changed

1 file changed

+95
-95
lines changed

src/sketch/shapes.rs

Lines changed: 95 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -965,101 +965,101 @@ impl<S: Clone + Debug + Send + Sync> Sketch<S> {
965965
/// - `backlash`: backlash allowance
966966
/// - `segments_per_flank`: tessellation resolution per tooth flank
967967
/// - `metadata`: optional metadata
968-
pub fn involute_gear(
969-
module_: Real,
970-
teeth: usize,
971-
pressure_angle_deg: Real,
972-
clearance: Real,
973-
backlash: Real,
974-
segments_per_flank: usize,
975-
metadata: Option<S>,
976-
) -> Sketch<S> {
977-
assert!(teeth >= 4, "Need at least 4 teeth");
978-
assert!(segments_per_flank >= 2);
979-
980-
let m = module_;
981-
let z = teeth as Real;
982-
let pressure_angle = pressure_angle_deg.to_radians();
983-
984-
// Standard gear dimensions
985-
let pitch_radius = 0.5 * m * z;
986-
let addendum = m;
987-
let dedendum = 1.25 * m + clearance;
988-
let outer_radius = pitch_radius + addendum;
989-
let base_radius = pitch_radius * pressure_angle.cos();
990-
let _root_radius = (pitch_radius - dedendum).max(base_radius * 0.9); // avoid < base
991-
992-
let angular_pitch = TAU / z;
993-
let tooth_thickness_at_pitch = angular_pitch / 2.0 - backlash / pitch_radius;
994-
let half_tooth_angle = tooth_thickness_at_pitch / 2.0;
995-
996-
// Helper: generate one involute flank from r1 to r2
997-
let generate_flank = |r_start: Real, r_end: Real, reverse: bool| -> Vec<(Real, Real)> {
998-
let mut pts = Vec::with_capacity(segments_per_flank + 1);
999-
for i in 0..=segments_per_flank {
1000-
let t = i as Real / segments_per_flank as Real;
1001-
let r = r_start + t * (r_end - r_start);
1002-
let phi = ((r / base_radius).powi(2) - 1.0).max(0.0).sqrt(); // involute angle
1003-
let (x, y) = (base_radius * (phi.cos() + phi * phi.sin()),
1004-
base_radius * (phi.sin() - phi * phi.cos()));
1005-
pts.push((x, y));
1006-
}
1007-
if reverse {
1008-
pts.reverse();
1009-
}
1010-
pts
1011-
};
1012-
1013-
// Build one full tooth (right flank + arc at tip + left flank + root arc)
1014-
let mut tooth_profile = Vec::new();
1015-
1016-
// Right flank: from base to outer
1017-
let right_flank = generate_flank(base_radius, outer_radius, false);
1018-
// Left flank: mirror and reverse
1019-
let left_flank: Vec<_> = right_flank.iter()
1020-
.map(|&(x, y)| (x, -y))
1021-
.rev()
1022-
.collect();
1023-
1024-
// Rotate flanks to align with tooth center
1025-
let rotate = |x: Real, y: Real, angle: Real| -> (Real, Real) {
1026-
let c = angle.cos();
1027-
let s = angle.sin();
1028-
(x * c - y * s, x * s + y * c)
1029-
};
1030-
1031-
// Angular offset from tooth center to flank start at base circle
1032-
let phi_base = ((pitch_radius / base_radius).powi(2) - 1.0).sqrt();
1033-
let inv_phi_base = phi_base - pressure_angle; // involute function value
1034-
let offset_angle = inv_phi_base + half_tooth_angle;
1035-
1036-
// Apply rotation to flanks
1037-
for &(x, y) in &right_flank {
1038-
tooth_profile.push(rotate(x, y, -offset_angle));
1039-
}
1040-
for &(x, y) in &left_flank {
1041-
tooth_profile.push(rotate(x, y, offset_angle));
1042-
}
1043-
1044-
// Close the tooth at the root with a small arc (optional but improves validity)
1045-
// For simplicity, we'll just connect to root circle with straight lines or small arc.
1046-
// But for now, connect last point to first via root radius approximation.
1047-
// Better: add root fillet, but we'll skip for brevity.
1048-
1049-
// Now replicate around the gear
1050-
let mut outline = Vec::with_capacity(tooth_profile.len() * teeth + 1);
1051-
for i in 0..teeth {
1052-
let rot = i as Real * angular_pitch;
1053-
let c = rot.cos();
1054-
let s = rot.sin();
1055-
for &(x, y) in &tooth_profile {
1056-
outline.push([x * c - y * s, x * s + y * c]);
1057-
}
1058-
}
1059-
outline.push(outline[0]); // close
1060-
1061-
Sketch::polygon(&outline, metadata)
1062-
}
968+
pub fn involute_gear(
969+
module_: Real,
970+
teeth: usize,
971+
pressure_angle_deg: Real,
972+
clearance: Real,
973+
backlash: Real,
974+
segments_per_flank: usize,
975+
metadata: Option<S>,
976+
) -> Sketch<S> {
977+
assert!(teeth >= 4, "Need at least 4 teeth");
978+
assert!(segments_per_flank >= 2);
979+
980+
let m = module_;
981+
let z = teeth as Real;
982+
let pressure_angle = pressure_angle_deg.to_radians();
983+
984+
// Standard gear dimensions
985+
let pitch_radius = 0.5 * m * z;
986+
let addendum = m;
987+
let dedendum = 1.25 * m + clearance;
988+
let outer_radius = pitch_radius + addendum;
989+
let base_radius = pitch_radius * pressure_angle.cos();
990+
let _root_radius = (pitch_radius - dedendum).max(base_radius * 0.9); // avoid < base
991+
992+
let angular_pitch = TAU / z;
993+
let tooth_thickness_at_pitch = angular_pitch / 2.0 - backlash / pitch_radius;
994+
let half_tooth_angle = tooth_thickness_at_pitch / 2.0;
995+
996+
// Helper: generate one involute flank from r1 to r2
997+
let generate_flank =
998+
|r_start: Real, r_end: Real, reverse: bool| -> Vec<(Real, Real)> {
999+
let mut pts = Vec::with_capacity(segments_per_flank + 1);
1000+
for i in 0..=segments_per_flank {
1001+
let t = i as Real / segments_per_flank as Real;
1002+
let r = r_start + t * (r_end - r_start);
1003+
let phi = ((r / base_radius).powi(2) - 1.0).max(0.0).sqrt(); // involute angle
1004+
let (x, y) = (
1005+
base_radius * (phi.cos() + phi * phi.sin()),
1006+
base_radius * (phi.sin() - phi * phi.cos()),
1007+
);
1008+
pts.push((x, y));
1009+
}
1010+
if reverse {
1011+
pts.reverse();
1012+
}
1013+
pts
1014+
};
1015+
1016+
// Build one full tooth (right flank + arc at tip + left flank + root arc)
1017+
let mut tooth_profile = Vec::new();
1018+
1019+
// Right flank: from base to outer
1020+
let right_flank = generate_flank(base_radius, outer_radius, false);
1021+
// Left flank: mirror and reverse
1022+
let left_flank: Vec<_> = right_flank.iter().map(|&(x, y)| (x, -y)).rev().collect();
1023+
1024+
// Rotate flanks to align with tooth center
1025+
let rotate = |x: Real, y: Real, angle: Real| -> (Real, Real) {
1026+
let c = angle.cos();
1027+
let s = angle.sin();
1028+
(x * c - y * s, x * s + y * c)
1029+
};
1030+
1031+
// Angular offset from tooth center to flank start at base circle
1032+
let phi_base = ((pitch_radius / base_radius).powi(2) - 1.0).sqrt();
1033+
let inv_phi_base = phi_base - pressure_angle; // involute function value
1034+
let offset_angle = inv_phi_base + half_tooth_angle;
1035+
1036+
// Apply rotation to flanks
1037+
for &(x, y) in &right_flank {
1038+
tooth_profile.push(rotate(x, y, -offset_angle));
1039+
}
1040+
for &(x, y) in &left_flank {
1041+
tooth_profile.push(rotate(x, y, offset_angle));
1042+
}
1043+
1044+
// Close the tooth at the root with a small arc (optional but improves validity)
1045+
// For simplicity, we'll just connect to root circle with straight lines or small arc.
1046+
// But for now, connect last point to first via root radius approximation.
1047+
// Better: add root fillet, but we'll skip for brevity.
1048+
1049+
// Now replicate around the gear
1050+
let mut outline = Vec::with_capacity(tooth_profile.len() * teeth + 1);
1051+
for i in 0..teeth {
1052+
let rot = i as Real * angular_pitch;
1053+
let c = rot.cos();
1054+
let s = rot.sin();
1055+
for &(x, y) in &tooth_profile {
1056+
outline.push([x * c - y * s, x * s + y * c]);
1057+
}
1058+
}
1059+
outline.push(outline[0]); // close
1060+
1061+
Sketch::polygon(&outline, metadata)
1062+
}
10631063

10641064
/// Generate an (epicyclic) cycloidal gear outline
10651065
///

0 commit comments

Comments
 (0)