Download or view airfoil.frink in plain text format
/** This library allows you to load and format various airfoils. It uses the
data available at the UIUC Airfoil Data site:
https://m-selig.ae.illinois.edu/ads.html
and the extensive UIUC Airfoil Coordinates Database:
https://m-selig.ae.illinois.edu/ads/coord_database.html
All of the airfoils can be downloaded from:
https://m-selig.ae.illinois.edu/ads/archives/coord_seligFmt.zip
You can plot airfoil shapes at:
http://airfoiltools.com/plotter/index
Airfoils in these databases are mostly listed in the "Selig" format named
for Michael S. Selig. The coordinates are in an x,y format starting from
trailing edge, along the upper surface to the leading edge and back around
the lower surface to trailing edge
For example, see E205 at
https://m-selig.ae.illinois.edu/ads/coord/e205.dat
Other airfols are in the "Lednicer" format which are upper surface points
leading edge to trailing edge and then lower surface leading edge to
trailing edge, separated by an intervening blank line.
For example, see Clark Y at
https://m-selig.ae.illinois.edu/ads/coord/clarky.dat
Some of the airfoils listed do not close at the trailing edge, i.e. the
trailing edge has a finite thickness as designed.
*/
class Airfoil
{
/** The name of the airfoil */
var name
/** An array of dimensionless [x,y] points in the "Selig" format. The
coordinates are in an x,y format starting from trailing edge, along the
upper surface to the leading edge and back around the lower surface to
trailing edge For example, see E205 at
https://m-selig.ae.illinois.edu/ads/coord/e205.dat
It is expected that the leading edge is at x=0 and the trailing edge is at
x=1 but this may not be guaranteed.
*/
var points
/** The upward rotation of the airfoil as an angle. This can be populated
when using the rotate method to create a new Airfoil. */
var rotation = 0 deg
/** Constructor. Creates a new airfoil. */
new[name, points] :=
{
this.name = name
this.points = points
}
/** This loads an airfoil definition from a Selig-formatted URL and returns
a new Airfoil object. */
class loadSelig[url] :=
{
lines = array[lines[url]]
name = trim[lines@0]
points = new array
LINE:
for i=1 to length[lines]-1
{
// For FrinkTNG this needs to be \p{Space}
if lines@i =~ %r/[^0-9eE\.[:space:]-]/
{
println["Rejecting line $i in $url: " + lines@i]
next LINE
}
[x,y] = eval[split[%r/\s+/, trim[lines@i]]]
if ! (isUnit[x] and isUnit[y])
next LINE
if y != undef
points.push[[x,y]]
}
return new Airfoil[name, points]
}
/** Creates a new (unclosed) polyline object from this airfoil. */
toPolyline[scaleX=1, scaleY=1] :=
{
return new polyline[getPoly[scaleX, scaleY]]
}
/** Creates a new (closed) polygon object from this airfoil. */
toPolygon[scaleX=1, scaleY=1] :=
{
return getPoly[scaleX, scaleY]
}
/** Creates a new (closed, filled) polygon object from this airfoil. */
toFilledPolygon[scaleX=1, scaleY=1] :=
{
return new filledPolygon[getPoly[scaleX, scaleY]]
}
/** Rotate the airfoil upward by the specified angle. The airfoil is
rotated around the specified x and y coordinates. If either coordinate
is undef, it is replaced by the geometric centroid of the wing.
It returns a new Airfoil object.
*/
rotate[angle, cx=undef, cy=undef] :=
{
if cx == undef || cy == undef
{
[cx1, cy1] = getPoly[].getCentroid[]
if cx == undef
cx = cx1
if cy == undef
cy = cy1
}
p1 = new array
for [x,y] = points
{
x1 = (x - cx) cos[-angle] - (y - cy) sin[-angle] + cx
y1 = (x - cx) sin[-angle] + (y - cy) cos[-angle] + cy
p1.push[[x1,y1]]
}
a = new Airfoil[name, p1]
a.rotation = this.rotation + angle
return a
}
/** Turns the array of points into a polygon object and returns it. */
getPoly[scaleX=1, scaleY=1] :=
{
poly = new polygon
for [x,y] = points
poly.addPoint[x scaleX, -y scaleY]
return poly
}
}
Download or view airfoil.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen was born 20217 days, 23 hours, 19 minutes ago.