rustfmt
This commit is contained in:
parent
5bb70ee2f8
commit
e90f9fd6b4
3 changed files with 136 additions and 67 deletions
|
@ -5,7 +5,7 @@ const IN2MM: f32 = 25.4;
|
||||||
pub const CHORD: f32 = 7.0 * IN2MM;
|
pub const CHORD: f32 = 7.0 * IN2MM;
|
||||||
pub const WING_TAPER: f32 = 0.6;
|
pub const WING_TAPER: f32 = 0.6;
|
||||||
pub const WINGSPAN: f32 = 45.0 * IN2MM;
|
pub const WINGSPAN: f32 = 45.0 * IN2MM;
|
||||||
pub const LENGTH: f32 = 30.0*IN2MM;
|
pub const LENGTH: f32 = 30.0 * IN2MM;
|
||||||
/// strut count in the main wing
|
/// strut count in the main wing
|
||||||
pub const STRUTS: usize = 12;
|
pub const STRUTS: usize = 12;
|
||||||
pub const CARDBOARD_WIDTH: f32 = 3.5;
|
pub const CARDBOARD_WIDTH: f32 = 3.5;
|
||||||
|
@ -14,13 +14,13 @@ pub const SPAR_SIDE_WIDTH: f32 = 0.75 * IN2MM;
|
||||||
pub const FUSELAGE_GAP: f32 = 0.4 * IN2MM;
|
pub const FUSELAGE_GAP: f32 = 0.4 * IN2MM;
|
||||||
/// a very large number, used to place unknown objects such that they do not intersect
|
/// a very large number, used to place unknown objects such that they do not intersect
|
||||||
pub const INF: f32 = 1000.0;
|
pub const INF: f32 = 1000.0;
|
||||||
pub const RUDDER_HEIGHT: f32 = 5.0 *IN2MM;
|
pub const RUDDER_HEIGHT: f32 = 5.0 * IN2MM;
|
||||||
pub const RUDDER_CHORD: f32 = 3.0 *IN2MM;
|
pub const RUDDER_CHORD: f32 = 3.0 * IN2MM;
|
||||||
pub const RUDDER_TAPER: f32 = 0.7;
|
pub const RUDDER_TAPER: f32 = 0.7;
|
||||||
pub const RUDDER_STRUTS: usize = 3;
|
pub const RUDDER_STRUTS: usize = 3;
|
||||||
pub const ELEVATOR_HEIGHT: f32 = 8.0 *IN2MM;
|
pub const ELEVATOR_HEIGHT: f32 = 8.0 * IN2MM;
|
||||||
pub const ELEVATOR_CHORD: f32 = 5.0 *IN2MM;
|
pub const ELEVATOR_CHORD: f32 = 5.0 * IN2MM;
|
||||||
pub const ELEVATOR_TAPER: f32 = 0.7;
|
pub const ELEVATOR_TAPER: f32 = 0.7;
|
||||||
pub const ELEVATOR_STRUTS: usize = 4;
|
pub const ELEVATOR_STRUTS: usize = 4;
|
||||||
pub const STOCK_HEIGHT: f32 = 25.0 *IN2MM;
|
pub const STOCK_HEIGHT: f32 = 25.0 * IN2MM;
|
||||||
pub const STOCK_WIDTH: f32 = 37.0 *IN2MM;
|
pub const STOCK_WIDTH: f32 = 37.0 * IN2MM;
|
||||||
|
|
149
src/main.rs
149
src/main.rs
|
@ -1,12 +1,12 @@
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use constants::*;
|
||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
use scad::*;
|
use scad::*;
|
||||||
use constants::*;
|
|
||||||
use selig::Span;
|
|
||||||
use selig::SeligFile;
|
|
||||||
use selig::Point;
|
use selig::Point;
|
||||||
|
use selig::SeligFile;
|
||||||
|
use selig::Span;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
mod constants;
|
mod constants;
|
||||||
mod selig;
|
mod selig;
|
||||||
|
@ -21,26 +21,49 @@ fn main() {
|
||||||
|
|
||||||
// cambered airfoil, used in the wing
|
// cambered airfoil, used in the wing
|
||||||
let wing_airfoil: SeligFile = SeligFile::parse(include_str!("../ag24.dat"));
|
let wing_airfoil: SeligFile = SeligFile::parse(include_str!("../ag24.dat"));
|
||||||
println!("name {}, perim {}", wing_airfoil.get_name(), wing_airfoil.get_points().length());
|
println!(
|
||||||
println!("desc {}", wing_airfoil.get_description().clone().unwrap_or("no desc".to_string()));
|
"name {}, perim {}",
|
||||||
|
wing_airfoil.get_name(),
|
||||||
|
wing_airfoil.get_points().length()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"desc {}",
|
||||||
|
wing_airfoil
|
||||||
|
.get_description()
|
||||||
|
.clone()
|
||||||
|
.unwrap_or("no desc".to_string())
|
||||||
|
);
|
||||||
//println!("span {:?}", points_in_range(wing_airfoil.get_points()[0..80], 0.0..1.0));
|
//println!("span {:?}", points_in_range(wing_airfoil.get_points()[0..80], 0.0..1.0));
|
||||||
|
|
||||||
let points = wing_airfoil.get_points()[0..80].to_vec();
|
let points = wing_airfoil.get_points()[0..80].to_vec();
|
||||||
let perimeter = points.length();
|
let perimeter = points.length();
|
||||||
let span = points.to_vec().points_in_range(perimeter * 0.4.. perimeter);
|
let span = points.to_vec().points_in_range(perimeter * 0.4..perimeter);
|
||||||
let points = scad::PolygonParameters::new(span);
|
let points = scad::PolygonParameters::new(span);
|
||||||
register_part(scad!(Polygon(points)));
|
register_part(scad!(Polygon(points)));
|
||||||
|
|
||||||
// symetric airfoil, used in the control surfaces
|
// symetric airfoil, used in the control surfaces
|
||||||
let control_airfoil: SeligFile = SeligFile::parse(include_str!("../edgevertical.dat"));
|
let control_airfoil: SeligFile = SeligFile::parse(include_str!("../edgevertical.dat"));
|
||||||
|
|
||||||
let mut wing_transform = scad!(Translate(vec3(0.0,0.0,0.0)));
|
let mut wing_transform = scad!(Translate(vec3(0.0, 0.0, 0.0)));
|
||||||
|
|
||||||
// struts
|
// struts
|
||||||
let mut symetric_spar = scad!(Union);
|
let mut symetric_spar = scad!(Union);
|
||||||
for port in [true,false] {
|
for port in [true, false] {
|
||||||
let mut wing = wing(&wing_airfoil, STRUTS/2, WINGSPAN/2.0, CHORD, CHORD * WING_TAPER, SparType::Top);
|
let mut wing = wing(
|
||||||
let top_spar = topwing_spar(&wing_airfoil, STRUTS/2, WINGSPAN/2.0, CHORD, CHORD * WING_TAPER);
|
&wing_airfoil,
|
||||||
|
STRUTS / 2,
|
||||||
|
WINGSPAN / 2.0,
|
||||||
|
CHORD,
|
||||||
|
CHORD * WING_TAPER,
|
||||||
|
SparType::Top,
|
||||||
|
);
|
||||||
|
let top_spar = topwing_spar(
|
||||||
|
&wing_airfoil,
|
||||||
|
STRUTS / 2,
|
||||||
|
WINGSPAN / 2.0,
|
||||||
|
CHORD,
|
||||||
|
CHORD * WING_TAPER,
|
||||||
|
);
|
||||||
|
|
||||||
let mut top_spar_neg = scad!(Difference; top_spar);
|
let mut top_spar_neg = scad!(Difference; top_spar);
|
||||||
top_spar_neg.add_child(wing.clone());
|
top_spar_neg.add_child(wing.clone());
|
||||||
|
@ -57,32 +80,52 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fuselage affixment point
|
// fuselage affixment point
|
||||||
symetric_spar.add_child(centered_cube(vec3(CHORD, FUSELAGE_GAP*2.0, 1.0), (false,true,false)));
|
symetric_spar.add_child(centered_cube(
|
||||||
|
vec3(CHORD, FUSELAGE_GAP * 2.0, 1.0),
|
||||||
|
(false, true, false),
|
||||||
|
));
|
||||||
wing_transform.add_child(symetric_spar.clone());
|
wing_transform.add_child(symetric_spar.clone());
|
||||||
register_part(scad!(Projection(false); symetric_spar));
|
register_part(scad!(Projection(false); symetric_spar));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// spars
|
// spars
|
||||||
|
|
||||||
// "fuselage"
|
// "fuselage"
|
||||||
scad_file.add_object(scad!(Rotate(-90.0, vec3(0.0, 0.0, 1.0));
|
scad_file.add_object(scad!(Rotate(-90.0, vec3(0.0, 0.0, 1.0));
|
||||||
spar(LENGTH, false))
|
spar(LENGTH, false)));
|
||||||
);
|
|
||||||
|
|
||||||
// rudder
|
// rudder
|
||||||
let mut rudder = scad!(Rotate(90.0, vec3(1.0, 0.0, 0.0)));
|
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, SparType::Center));
|
rudder.add_child(wing(
|
||||||
|
&control_airfoil,
|
||||||
|
RUDDER_STRUTS,
|
||||||
|
RUDDER_HEIGHT,
|
||||||
|
RUDDER_CHORD,
|
||||||
|
RUDDER_CHORD * RUDDER_TAPER,
|
||||||
|
SparType::Center,
|
||||||
|
));
|
||||||
rudder.add_child(spar(RUDDER_HEIGHT, false));
|
rudder.add_child(spar(RUDDER_HEIGHT, false));
|
||||||
rudder = scad!(Translate(vec3(LENGTH-RUDDER_CHORD, 0.0, 0.0)); rudder);
|
rudder = scad!(Translate(vec3(LENGTH-RUDDER_CHORD, 0.0, 0.0)); rudder);
|
||||||
scad_file.add_object(rudder);
|
scad_file.add_object(rudder);
|
||||||
|
|
||||||
// elevator
|
// elevator
|
||||||
let mut elevator = scad!(Translate(vec3(LENGTH-ELEVATOR_CHORD, 0.0,0.0)));
|
let mut elevator = scad!(Translate(vec3(LENGTH - ELEVATOR_CHORD, 0.0, 0.0)));
|
||||||
let mut symetric_spar = scad!(Union);
|
let mut symetric_spar = scad!(Union);
|
||||||
for port in [true,false] {
|
for port in [true, false] {
|
||||||
let mut wing = wing(&wing_airfoil, ELEVATOR_STRUTS, ELEVATOR_HEIGHT, ELEVATOR_CHORD, ELEVATOR_CHORD * ELEVATOR_TAPER, SparType::Top);
|
let mut wing = wing(
|
||||||
let top_spar = topwing_spar(&wing_airfoil, ELEVATOR_STRUTS, ELEVATOR_HEIGHT, ELEVATOR_CHORD, ELEVATOR_CHORD * ELEVATOR_TAPER);
|
&wing_airfoil,
|
||||||
|
ELEVATOR_STRUTS,
|
||||||
|
ELEVATOR_HEIGHT,
|
||||||
|
ELEVATOR_CHORD,
|
||||||
|
ELEVATOR_CHORD * ELEVATOR_TAPER,
|
||||||
|
SparType::Top,
|
||||||
|
);
|
||||||
|
let top_spar = topwing_spar(
|
||||||
|
&wing_airfoil,
|
||||||
|
ELEVATOR_STRUTS,
|
||||||
|
ELEVATOR_HEIGHT,
|
||||||
|
ELEVATOR_CHORD,
|
||||||
|
ELEVATOR_CHORD * ELEVATOR_TAPER,
|
||||||
|
);
|
||||||
let mut top_spar_neg = scad!(Difference; top_spar);
|
let mut top_spar_neg = scad!(Difference; top_spar);
|
||||||
top_spar_neg.add_child(wing.clone());
|
top_spar_neg.add_child(wing.clone());
|
||||||
symetric_spar.add_child(top_spar_neg.clone());
|
symetric_spar.add_child(top_spar_neg.clone());
|
||||||
|
@ -94,17 +137,19 @@ fn main() {
|
||||||
}
|
}
|
||||||
scad_file.add_object(elevator);
|
scad_file.add_object(elevator);
|
||||||
|
|
||||||
symetric_spar.add_child(centered_cube(vec3(CHORD, FUSELAGE_GAP*2.0, 1.0), (false,true,false)));
|
symetric_spar.add_child(centered_cube(
|
||||||
|
vec3(CHORD, FUSELAGE_GAP * 2.0, 1.0),
|
||||||
|
(false, true, false),
|
||||||
|
));
|
||||||
register_part(scad!(Projection(false); symetric_spar));
|
register_part(scad!(Projection(false); symetric_spar));
|
||||||
|
|
||||||
|
|
||||||
let cardboard = vec3(0.38, 0.26, 0.26);
|
let cardboard = vec3(0.38, 0.26, 0.26);
|
||||||
scad_file.add_object(scad!(Color(cardboard); wing_transform));
|
scad_file.add_object(scad!(Color(cardboard); wing_transform));
|
||||||
|
|
||||||
scad_file.write_to_file(String::from("build/assembly.scad"));
|
scad_file.write_to_file(String::from("build/assembly.scad"));
|
||||||
|
|
||||||
for (idx, part) in PARTS.lock().unwrap().clone().into_iter().enumerate() {
|
for (idx, part) in PARTS.lock().unwrap().clone().into_iter().enumerate() {
|
||||||
let mut file = ScadFile::new();
|
let mut file = ScadFile::new();
|
||||||
file.set_detail(50);
|
file.set_detail(50);
|
||||||
file.add_object(part);
|
file.add_object(part);
|
||||||
file.write_to_file(format!("build/part{idx}.scad"));
|
file.write_to_file(format!("build/part{idx}.scad"));
|
||||||
|
@ -134,7 +179,7 @@ fn strut(airfoil: &SeligFile, chord: f32, width: f32, spar: &SparType) -> ScadOb
|
||||||
SparType::Top => topspar_negative(airfoil, chord, 0.1..0.6),
|
SparType::Top => topspar_negative(airfoil, chord, 0.1..0.6),
|
||||||
SparType::Center => {
|
SparType::Center => {
|
||||||
scad!(Union)
|
scad!(Union)
|
||||||
},
|
}
|
||||||
SparType::None => {
|
SparType::None => {
|
||||||
scad!(Union)
|
scad!(Union)
|
||||||
}
|
}
|
||||||
|
@ -144,7 +189,13 @@ fn strut(airfoil: &SeligFile, chord: f32, width: f32, spar: &SparType) -> ScadOb
|
||||||
extrude_strut(shape, strut_hole, width, chord, true)
|
extrude_strut(shape, strut_hole, width, chord, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extrude_strut(shape: ScadObject, strut_hole: ScadObject, width: f32, chord: f32, register:bool) -> ScadObject {
|
fn extrude_strut(
|
||||||
|
shape: ScadObject,
|
||||||
|
strut_hole: ScadObject,
|
||||||
|
width: f32,
|
||||||
|
chord: f32,
|
||||||
|
register: bool,
|
||||||
|
) -> ScadObject {
|
||||||
let mut strut_shape = scad!(Difference);
|
let mut strut_shape = scad!(Difference);
|
||||||
strut_shape.add_child(shape);
|
strut_shape.add_child(shape);
|
||||||
strut_shape.add_child(strut_hole);
|
strut_shape.add_child(strut_hole);
|
||||||
|
@ -169,16 +220,18 @@ fn extrude_strut(shape: ScadObject, strut_hole: ScadObject, width: f32, chord: f
|
||||||
|
|
||||||
fn topspar_negative(airfoil: &SeligFile, chord: f32, range: Range<f32>) -> ScadObject {
|
fn topspar_negative(airfoil: &SeligFile, chord: f32, range: Range<f32>) -> ScadObject {
|
||||||
let points = airfoil.get_points();
|
let points = airfoil.get_points();
|
||||||
let points = &points[0.. points.len() / 2];
|
let points = &points[0..points.len() / 2];
|
||||||
let perimeter = span_length(points);
|
let perimeter = span_length(points);
|
||||||
|
|
||||||
let span = points.to_vec().points_in_range(perimeter * (1.0-range.end) .. perimeter * (1.0-range.start));
|
let span = points
|
||||||
|
.to_vec()
|
||||||
|
.points_in_range(perimeter * (1.0 - range.end)..perimeter * (1.0 - range.start));
|
||||||
|
|
||||||
let mut mask = scad!(Union);
|
let mut mask = scad!(Union);
|
||||||
|
|
||||||
let mut last: Option<ScadObject> = None;
|
let mut last: Option<ScadObject> = None;
|
||||||
for point in span {
|
for point in span {
|
||||||
let mut current = scad!(Square(vec2(0.001/ chord, CARDBOARD_WIDTH / chord)));
|
let mut current = scad!(Square(vec2(0.001 / chord, CARDBOARD_WIDTH / chord)));
|
||||||
current = scad!(Translate2d(point.clone() - vec2(0.0, CARDBOARD_WIDTH/chord)); current);
|
current = scad!(Translate2d(point.clone() - vec2(0.0, CARDBOARD_WIDTH/chord)); current);
|
||||||
if let Some(last_mask) = last {
|
if let Some(last_mask) = last {
|
||||||
let mut hull = scad!(Hull);
|
let mut hull = scad!(Hull);
|
||||||
|
@ -202,7 +255,7 @@ fn spar(length: f32, center: bool) -> ScadObject {
|
||||||
if center {
|
if center {
|
||||||
panel = scad!(Translate(vec3(0.0, -length/2.0, 0.0)); panel)
|
panel = scad!(Translate(vec3(0.0, -length/2.0, 0.0)); panel)
|
||||||
}
|
}
|
||||||
let rot = 120.0 * i as f32;
|
let rot = 120.0 * i as f32;
|
||||||
spar.add_child(scad!(
|
spar.add_child(scad!(
|
||||||
Rotate(rot, vec3(0.0, 1.0, 0.0)); panel
|
Rotate(rot, vec3(0.0, 1.0, 0.0)); panel
|
||||||
));
|
));
|
||||||
|
@ -215,23 +268,29 @@ fn register_part(part: ScadObject) {
|
||||||
PARTS.lock().unwrap().push(part);
|
PARTS.lock().unwrap().push(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lerp(a: f32, b:f32, x:f32) -> f32 {
|
fn lerp(a: f32, b: f32, x: f32) -> f32 {
|
||||||
a*(1.0-x) + b*x
|
a * (1.0 - x) + b * x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wing(aerofoil: &SeligFile, struts: usize, length: f32, chord: f32, taper: f32, spar: SparType) -> ScadObject {
|
fn wing(
|
||||||
let mut wing = scad!(Translate(vec3(0.0,0.0,0.0)));
|
aerofoil: &SeligFile,
|
||||||
|
struts: usize,
|
||||||
|
length: f32,
|
||||||
|
chord: f32,
|
||||||
|
taper: f32,
|
||||||
|
spar: SparType,
|
||||||
|
) -> ScadObject {
|
||||||
|
let mut wing = scad!(Translate(vec3(0.0, 0.0, 0.0)));
|
||||||
|
|
||||||
// struts
|
// struts
|
||||||
for strut_idx in 0..struts + 1 {
|
for strut_idx in 0..struts + 1 {
|
||||||
|
let gap = length / struts as f32;
|
||||||
let gap = length/struts as f32;
|
|
||||||
|
|
||||||
let chord = lerp(chord, taper, strut_idx as f32 / struts as f32);
|
let chord = lerp(chord, taper, strut_idx as f32 / struts as f32);
|
||||||
|
|
||||||
let spacing = strut_idx as f32 * gap;
|
let spacing = strut_idx as f32 * gap;
|
||||||
|
|
||||||
let mut transform = scad!(Translate(vec3(0.0, spacing ,0.0)));
|
let mut transform = scad!(Translate(vec3(0.0, spacing, 0.0)));
|
||||||
|
|
||||||
let strut = strut(&aerofoil, chord, CARDBOARD_WIDTH, &spar);
|
let strut = strut(&aerofoil, chord, CARDBOARD_WIDTH, &spar);
|
||||||
transform.add_child(strut);
|
transform.add_child(strut);
|
||||||
|
@ -241,16 +300,21 @@ fn wing(aerofoil: &SeligFile, struts: usize, length: f32, chord: f32, taper: f32
|
||||||
wing
|
wing
|
||||||
}
|
}
|
||||||
|
|
||||||
fn topwing_spar(aerofoil: &SeligFile, struts: usize, length: f32, chord: f32, taper: f32) -> ScadObject {
|
fn topwing_spar(
|
||||||
|
aerofoil: &SeligFile,
|
||||||
|
struts: usize,
|
||||||
|
length: f32,
|
||||||
|
chord: f32,
|
||||||
|
taper: f32,
|
||||||
|
) -> ScadObject {
|
||||||
let mut wing = scad!(Hull);
|
let mut wing = scad!(Hull);
|
||||||
|
|
||||||
let mut last_segment : Option<ScadObject> = None;
|
let mut last_segment: Option<ScadObject> = None;
|
||||||
let mut pre_vis = scad!(Union);
|
let mut pre_vis = scad!(Union);
|
||||||
|
|
||||||
// struts
|
// struts
|
||||||
for strut_idx in 0..struts + 1 {
|
for strut_idx in 0..struts + 1 {
|
||||||
|
let gap = length / struts as f32;
|
||||||
let gap = length/struts as f32;
|
|
||||||
|
|
||||||
let chord = lerp(chord, taper, strut_idx as f32 / struts as f32);
|
let chord = lerp(chord, taper, strut_idx as f32 / struts as f32);
|
||||||
|
|
||||||
|
@ -259,10 +323,9 @@ fn topwing_spar(aerofoil: &SeligFile, struts: usize, length: f32, chord: f32, ta
|
||||||
let shape = topspar_negative(&aerofoil, chord, 0.1..0.6);
|
let shape = topspar_negative(&aerofoil, chord, 0.1..0.6);
|
||||||
let extruded = extrude_strut(shape.clone(), scad!(Union), CARDBOARD_WIDTH, chord, false);
|
let extruded = extrude_strut(shape.clone(), scad!(Union), CARDBOARD_WIDTH, chord, false);
|
||||||
|
|
||||||
let mut transform = scad!(Translate(vec3(0.0, spacing ,0.0)));
|
let mut transform = scad!(Translate(vec3(0.0, spacing, 0.0)));
|
||||||
transform.add_child(extruded);
|
transform.add_child(extruded);
|
||||||
|
|
||||||
|
|
||||||
// in betweens
|
// in betweens
|
||||||
if let Some(last) = last_segment {
|
if let Some(last) = last_segment {
|
||||||
let mut hull = scad!(Hull);
|
let mut hull = scad!(Hull);
|
||||||
|
@ -272,7 +335,7 @@ fn topwing_spar(aerofoil: &SeligFile, struts: usize, length: f32, chord: f32, ta
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut last_t = scad!(Translate(vec3(0.0, -gap ,0.0)));
|
let mut last_t = scad!(Translate(vec3(0.0, -gap, 0.0)));
|
||||||
last_t.add_child(scad!(LinearExtrude(extrude.clone()); last));
|
last_t.add_child(scad!(LinearExtrude(extrude.clone()); last));
|
||||||
//hull.add_child(last_t);
|
//hull.add_child(last_t);
|
||||||
//hull.add_child(scad!(LinearExtrude(extrude); shape.clone()));
|
//hull.add_child(scad!(LinearExtrude(extrude); shape.clone()));
|
||||||
|
|
40
src/selig.rs
40
src/selig.rs
|
@ -1,7 +1,4 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::ops::RangeFull;
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::ops::Index;
|
|
||||||
|
|
||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
|
|
||||||
|
@ -19,20 +16,24 @@ impl SeligFile {
|
||||||
let mut points = Vec::new();
|
let mut points = Vec::new();
|
||||||
|
|
||||||
let mut lines = file.lines();
|
let mut lines = file.lines();
|
||||||
let mut header = lines.next().expect("selig .dat is empty").split(" | ").map(|x| x.trim());
|
let mut header = lines
|
||||||
|
.next()
|
||||||
|
.expect("selig .dat is empty")
|
||||||
|
.split(" | ")
|
||||||
|
.map(|x| x.trim());
|
||||||
let name = header.next().unwrap().to_string();
|
let name = header.next().unwrap().to_string();
|
||||||
let description = header.next().map(|d| d.to_string());
|
let description = header.next().map(|d| d.to_string());
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let mut numbers =line.split(" ").filter(|n| !n.trim().is_empty());
|
let mut numbers = line.split(" ").filter(|n| !n.trim().is_empty());
|
||||||
let x = numbers.next().unwrap().parse().unwrap();
|
let x = numbers.next().unwrap().parse().unwrap();
|
||||||
let y = numbers.next().unwrap().parse().unwrap();
|
let y = numbers.next().unwrap().parse().unwrap();
|
||||||
points.push(Point::new(x,y))
|
points.push(Point::new(x, y))
|
||||||
}
|
}
|
||||||
SeligFile {
|
SeligFile {
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
data: points
|
data: points,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +48,6 @@ impl SeligFile {
|
||||||
pub fn get_description(&self) -> &Option<String> {
|
pub fn get_description(&self) -> &Option<String> {
|
||||||
&self.description
|
&self.description
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Span {
|
pub trait Span {
|
||||||
|
@ -79,21 +79,27 @@ impl Span for Airfoil {
|
||||||
for point in self {
|
for point in self {
|
||||||
if let Some(last) = last_point {
|
if let Some(last) = last_point {
|
||||||
let span: f32 = (last - point).magnitude();
|
let span: f32 = (last - point).magnitude();
|
||||||
match (range.contains(&distance), range.contains(&(distance+span))) {
|
match (
|
||||||
(true, true) => { // fully within span
|
range.contains(&distance),
|
||||||
|
range.contains(&(distance + span)),
|
||||||
|
) {
|
||||||
|
(true, true) => {
|
||||||
|
// fully within span
|
||||||
points.push(point.clone());
|
points.push(point.clone());
|
||||||
},
|
}
|
||||||
(false, true) => { // entering span
|
(false, true) => {
|
||||||
|
// entering span
|
||||||
let undershoot = distance - range.start;
|
let undershoot = distance - range.start;
|
||||||
let part_out = (span - undershoot) / span;
|
let part_out = (span - undershoot) / span;
|
||||||
points.push(last.lerp(&point, part_out));
|
points.push(last.lerp(&point, part_out));
|
||||||
},
|
}
|
||||||
(true, false) => { // exiting span
|
(true, false) => {
|
||||||
|
// exiting span
|
||||||
let overshoot = range.end - distance;
|
let overshoot = range.end - distance;
|
||||||
let part_in = (span - overshoot) / span;
|
let part_in = (span - overshoot) / span;
|
||||||
points.push(last.lerp(&point, part_in));
|
points.push(last.lerp(&point, part_in));
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
distance += span;
|
distance += span;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +111,7 @@ impl Span for Airfoil {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Span, SeligFile};
|
use super::{SeligFile, Span};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn full_perimiter() {
|
fn full_perimiter() {
|
||||||
|
|
Loading…
Reference in a new issue