diff --git a/src/constants.rs b/src/constants.rs index c1c4901..8166df5 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,3 +1,5 @@ +use crate::WingConfig; + /// Constants /// the native unit is mm @@ -8,6 +10,12 @@ pub const WINGSPAN: f32 = 45.0 * IN2MM; pub const LENGTH: f32 = 30.0 * IN2MM; /// strut count in the main wing pub const STRUTS: usize = 12; +pub const WING: WingConfig = WingConfig { + length: WINGSPAN / 2.0, + chord: CHORD, + taper: WING_TAPER, + struts: STRUTS / 2, +}; pub const CARDBOARD_WIDTH: f32 = 3.5; /// length of each side of the triangular spar pub const SPAR_SIDE_WIDTH: f32 = 0.75 * IN2MM; @@ -18,9 +26,21 @@ pub const RUDDER_HEIGHT: f32 = 5.0 * IN2MM; pub const RUDDER_CHORD: f32 = 3.0 * IN2MM; pub const RUDDER_TAPER: f32 = 0.7; pub const RUDDER_STRUTS: usize = 3; +pub const RUDDER: WingConfig = WingConfig { + length: RUDDER_HEIGHT, + chord: RUDDER_CHORD, + taper: RUDDER_TAPER, + struts: RUDDER_STRUTS, +}; pub const ELEVATOR_HEIGHT: f32 = 8.0 * IN2MM; pub const ELEVATOR_CHORD: f32 = 5.0 * IN2MM; pub const ELEVATOR_TAPER: f32 = 0.7; pub const ELEVATOR_STRUTS: usize = 4; +pub const ELEVATOR: WingConfig = WingConfig { + length: ELEVATOR_HEIGHT, + chord: ELEVATOR_CHORD, + taper: ELEVATOR_TAPER, + struts: ELEVATOR_STRUTS, +}; pub const STOCK_HEIGHT: f32 = 25.0 * IN2MM; pub const STOCK_WIDTH: f32 = 37.0 * IN2MM; diff --git a/src/main.rs b/src/main.rs index b9a701a..2b5dda1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,7 @@ fn main() { // symetric airfoil, used in the control surfaces let control_airfoil: SeligFile = SeligFile::parse(include_str!("../edgevertical.dat")); - let wing_transform = mirrored_wing(&wing_airfoil); + let wing_transform = mirrored_wing(&wing_airfoil, &WING); // spars @@ -48,10 +48,7 @@ fn main() { let mut rudder = scad!(Rotate(90.0, vec3(1.0, 0.0, 0.0))); rudder.add_child(wing( &control_airfoil, - RUDDER_STRUTS, - RUDDER_HEIGHT, - RUDDER_CHORD, - RUDDER_CHORD * RUDDER_TAPER, + &RUDDER, SparType::Center, )); rudder.add_child(spar(RUDDER_HEIGHT, false)); @@ -64,10 +61,7 @@ fn main() { for port in [true, false] { let mut wing = wing( &wing_airfoil, - ELEVATOR_STRUTS, - ELEVATOR_HEIGHT, - ELEVATOR_CHORD, - ELEVATOR_CHORD * ELEVATOR_TAPER, + &ELEVATOR, SparType::Top, ); let top_spar = topwing_spar( @@ -135,7 +129,7 @@ impl Construct { } } -fn mirrored_wing(wing_airfoil: &SeligFile) -> Construct { +fn mirrored_wing(wing_airfoil: &SeligFile, wing_config: &WingConfig) -> Construct { let mut parts = Vec::new(); let mut wing_transform = scad!(Translate(vec3(0.0, 0.0, 0.0))); // struts @@ -143,10 +137,7 @@ fn mirrored_wing(wing_airfoil: &SeligFile) -> Construct { for port in [true, false] { let mut wing = wing( wing_airfoil, - STRUTS / 2, - WINGSPAN / 2.0, - CHORD, - CHORD * WING_TAPER, + &wing_config, SparType::Top, ); let top_spar = topwing_spar( @@ -189,9 +180,10 @@ enum SparType { } /// returns a extruded airfoil with the given dimensions -fn strut(airfoil: &SeligFile, chord: f32, width: f32, spar: &SparType) -> ScadObject { +fn strut(airfoil: &SeligFile, chord: f32, width: f32, spar: &SparType) -> Construct { let aerofoil = scad::PolygonParameters::new(airfoil.get_points().to_vec()); let shape = scad!(Polygon(aerofoil)); + let mut parts = Vec::new(); let strut_hole = { match spar { @@ -205,7 +197,29 @@ fn strut(airfoil: &SeligFile, chord: f32, width: f32, spar: &SparType) -> ScadOb } }; - extrude_strut(shape, strut_hole, width, chord, true) + let shape = shape; + let chord = chord; + let mut strut_shape = scad!(Difference); + strut_shape.add_child(shape); + strut_shape.add_child(strut_hole); + + let shape = strut_shape; + + let extrude = LinExtrudeParams { + height: width, + center: true, + ..Default::default() + }; + + let unit: Vector3 = Vector3::new(1.0, 1.0, 1.0); + let scaled = scad!(Scale(unit * chord); shape); + parts.push(scaled.clone()); + let strut = scad!(LinearExtrude(extrude); scaled); + let rotated = scad!(Rotate(90.0, vec3(1.0, 0.0, 0.0)); strut); + Construct { + visualization: rotated, + parts, + } } fn extrude_strut( @@ -293,26 +307,23 @@ fn lerp(a: f32, b: f32, x: f32) -> f32 { fn wing( aerofoil: &SeligFile, - struts: usize, - length: f32, - chord: f32, - taper: f32, + config: &WingConfig, spar: SparType, ) -> ScadObject { let mut wing = scad!(Translate(vec3(0.0, 0.0, 0.0))); // struts - for strut_idx in 0..struts + 1 { - let gap = length / struts as f32; + for strut_idx in 0..config.struts + 1 { + let gap = config.length / config.struts as f32; - let chord = lerp(chord, taper, strut_idx as f32 / struts as f32); + let chord = lerp(config.chord, config.chord * config.taper, strut_idx as f32 / config.struts as f32); let spacing = strut_idx as f32 * gap; let mut transform = scad!(Translate(vec3(0.0, spacing, 0.0))); let strut = strut(aerofoil, chord, CARDBOARD_WIDTH, &spar); - transform.add_child(strut); + transform.add_child(strut.visualization); wing.add_child(transform); } @@ -372,4 +383,11 @@ fn topwing_spar( wing } - +/// Parameters for what would be half of a symmetrical (port/starboard) wing +/// All distance units are millimeters +pub struct WingConfig { + pub length: f32, /// half of the wingspan + pub chord: f32, + pub taper: f32, /// chord at wingtip in relation to the chord at the root + pub struts: usize, +}