-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathairfoil.scad
105 lines (88 loc) · 5.33 KB
/
airfoil.scad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
$airfoil_fn = 120;
$close_airfoils = true;
//https://en.wikipedia.org/wiki/NACA_airfoil
function foil_y(x, c, t) =
(5*t*c)*( ( 0.2969 * sqrt(x/c) ) - ( 0.1260*(x/c) ) - ( 0.3516*pow((x/c),2) ) + ( 0.2843*pow((x/c),3) ) - ( ( $close_airfoils ? 0.1036 : 0.1015)*pow((x/c),4) ) ); //NACA symetrical airfoil formula
function camber(x,c,m,p) = ( x <= (p * c) ?
( ( (c * m)/pow( p, 2 ) ) * ( ( 2 * p * (x / c) ) - pow( (x / c) , 2) ) ) :
( ( (c * m)/pow((1 - p),2) ) * ( (1-(2 * p) ) + ( 2 * p * (x / c) ) - pow( (x / c) , 2)))
);
function theta(x,c,m,p) = ( x <= (p * c) ?
atan( ((m)/pow(p,2)) * (p - (x / c)) ) :
atan( ((m)/pow((1 - p),2)) * (p - (x / c)) )
);
function camber_y(x,c,t,m,p, upper=true) = ( upper == true ?
( camber(x,c,m,p) + (foil_y(x,c,t) * cos( theta(x,c,m,p) ) ) ) :
( camber(x,c,m,p) - (foil_y(x,c,t) * cos( theta(x,c,m,p) ) ) )
);
function camber_x(x,c,t,m,p, upper=true) = ( upper == true ?
( x - (foil_y(x,c,t) * sin( theta(x,c,m,p) ) ) ) :
( x + (foil_y(x,c,t) * sin( theta(x,c,m,p) ) ) )
);
module airfoil_poly (c = 100, naca = 0015, raw=false) {
$close_airfoils = ($close_airfoils != undef) ? $close_airfoils : false;
$airfoil_fn = ($airfoil_fn != undef) ? $airfoil_fn : 100;
res = c/$airfoil_fn; //resolution of foil poly
//establish thickness/length ratio
t = (raw == false) ? ((naca%100)/100) : raw[2];
// maximum camber:chord
m = (raw == false) ?((floor((((naca-(naca%100))/1000))) /100) ):raw[0];
//distance of maximum camber from the airfoil leading edge in tenths of the chord
p = (raw == false) ?((((naca-(naca%100))/100)%10) / 10): raw[1];
// points have to be generated with or without camber, depending.
points_u = ( m == 0 || p == 0) ?
[for (i = [0:res:c]) let (x = i, y = foil_y(i,c,t) ) [x,y]] :
[for (i = [0:res:c]) let (x = camber_x(i,c,t,m,p), y = camber_y(i,c,t,m,p) ) [x,y]] ;
points_l = ( m == 0 || p == 0) ?
[for (i = [c:-1*res:0]) let (x = i, y = foil_y(i,c,t) * -1 ) [x,y]] :
[for (i = [c:-1*res:0]) let (x = camber_x(i,c,t,m,p,upper=false), y = camber_y(i,c,t,m,p, upper=false) ) [x,y]] ;
polygon(concat(points_u,points_l)); //draw poly
}
//Todo: Wings, w/angles
// Airfoil definition = [c,naca]
module airfoil_simple_wing (airfoils=false, wing_angle=[0,0], wing_length=1000){
if (airfoils != false) {
if (len(airfoils[0]) == undef) {
hull(){
linear_extrude(0.1) airfoil_poly(airfoils[0],airfoils[1]);
translate([(sin(wing_angle[0]) * wing_length),(sin(wing_angle[1]) * wing_length),wing_length]) linear_extrude(0.1) airfoil_poly(airfoils[0],airfoils[1]);
}
}
else {
union(){
for( i=[1:len(airfoils)-1] ) {
hull() {
translate([(sin(wing_angle[0]) * wing_length * (i-1)/len(airfoils)),
(sin(wing_angle[1]) * wing_length * (i-1)/len(airfoils)),
wing_length * (i-1)/len(airfoils)])
linear_extrude(0.1) airfoil_poly(airfoils[(i-1)][0],airfoils[(i-1)][1]);
translate([(sin(wing_angle[0]) * wing_length * i/len(airfoils)),
(sin(wing_angle[1]) * wing_length * i/len(airfoils)),
wing_length * i/len(airfoils)])
linear_extrude(0.1) airfoil_poly(airfoils[i][0],airfoils[i][1]);
}
}
}
}
} else {
echo("No Airfoils defined! Airfoils should be a set of [chord, naca]. Specify one for a uniform wing, two or more for compound wing. If specifying only one, do not put it in a set/vector. Multiple airfoils will be spaced evenly along the wing length.");
}
}
module airfoil_help(){
echo("<u><b>Parametric Airfoil and Wing generator v0.1</u></b> <br>\
For a brief overview of the math and specifications used, see https://en.wikipedia.org/wiki/NACA_airfoil<br>\
<u>Globals:</u><br> \
<b><i>$close_airfoils</b></i>: Defines whether you want the back of your air foils closed, or if you want them open (default: false) <br>\
<b><i>$airfoil_fn</b></i>: number of sides for your airfoil. (default: 100) <br>\
<u>airfoil_poly help:</u><br>\
<b><i>c</b></i>: Chord length, this is the chord length of your airfoil. (default: 100) <br>\
<b><i>naca</b></i>: The NACA 4-digit specification for your airfoil. (default: 0015) <br>\
<b><i>raw</b></i>: overrides the NACA code with direct ratios. Provide in the same order as the NACA digits. (e.g NACA 4123 becomes raw [.4,.1,.23])<br>
<u>airfoil_simple_wing help:</u> <br>\
<b><i>airfoils</b></i>: Airfoils should be a set of [chord, naca]. Specify one for a uniform wing, two or more in a vector for compound wing. If specifying only one, do not put it in a set/vector. Multiple airfoils will be spaced evenly along the wing length. (required)<br>\
<b><i>wing_angle</b></i>: a set of angles, [sweep,slope] (optional, default=[0,0])<br>\
<b><i>wing_length</b></i>: length of the wing (optional, default=1000)");
}
airfoil_help();
//translate([0,0,100]) airfoil_poly();
//airfoil_simple_wing(airfoils=[[100,0015],[200,2414],[100,0015],[200,2414],[100,0015]], wing_angle=[20,-20]);