A Better Way to Draw Airfoils in NURBS Modeling Packages

This post, and the methods I describe below stemmed from my interest in surface modeling aircraft structures in Rhino3D, and the problems I encountered along the way. While this method is especially crucial to those using T-Splines, anyone drawing airfoils using a NURBS based modeling package will find the information interesting. While the commands my be specific to Rhino and T-Splines, the concepts are universal to every CAD package I’ve encountered. So with that…..

Airfoils. At their most basic conceptual level, they are a thickness distribution, often with a camber deflection. For many airfoils, these are mathematically derived, and then the airfoil data is put into an ordinate file. When we go to design an airplane in a surface modeling package, we must take that ordinate file and create the best possible representation of the airfoil so that the wing will fly in a predictable and expected manner. So let’s start by looking at how most people seem to be doing it currently.

I use Profili Pro 2 for airfoil database management. There’s plenty of programs out there that do roughly the same thing, I happen to like Profili because it has Xfoil integrated into it, and you can also quickly and easily modify the trailing edge thickness of your airfoil. For those who are just interested in making surface models, a razor sharp trailing edge is of no worry, but for those of us who want to manufacture what we’re drawing, it helps to be able to make a non-zero trailing edge quickly and easily. For the sake of this discussion, I’ll be using a NACA 0010 airfoil with a zero thickness trailing edge. The NACA 00 series airfoils are commonly used on tail surfaces of full size aircraft. The 0010 section might be considered by some to be a bit thin, but as you’ll see down the road, by making it 10% thick, it’s quite easy to bump it to say 12% in Rhino, or whatever thickness you desire. Okay, so starting in Profili, I open up the Airfoils Managment library, and bring up a NACA 0010 section. The best way to get the section out of Profili as a dxf is a little non-intuitive. You go to Rib-templates->Begin Printing. I zero out and deselect everything except draw chord line. If you’ve made a finite trailing edge thickness for a specific chord length, make sure that the chord length matches the intended chord of the section. A template will pop up, then go to Print->Export on a .DXF File.

Now open up Rhino, and create a file, making sure it’s the same units as your airfoil. Then go to File->Import and select .dxf files from the drop down, and navigate to your file. Here’s what you’ll get:

Importing .dxf file into Rhino

Notice that you get a bunch of layers imported from the Profili .dxf file. I would suggest moving the linework you see to a layer called something like “DXF Airfoil” and then deleting all the extra layers. Okay so what we have here looks a whole lot like an airfoil, but what is it exactly? Well, using the “what” command in Rhino V5, we get the following:

So we know that while it looks smooth, it’s a polyline, which means it’s made up of straight line segments, 258 of them to be exact. Turning the PointsOn and zooming in confirms this:

From a surface modeling perspective, we can’t make nice smooth surfaces from this, because what appears to be a smooth curve is not. So we need to convert this to a curve. What Rhino calls a curve some software calls a spline, but they’re the same thing – a NURBS curve. Here’s how most people accomplish this in Rhino – Start by copying the polyline onto a new layer, let’s call this one InterpCrv. Turn off DXF Airfoil. Then go Curve->Freeform->Fit to Polyline. You’ve got a few options to select. The important ones are the degree and the curve type, which should be set to 3 and Interpolated. An Interpolated curve means that the curve will pass through the verticies of your polyline, which is what you want. Delete the input polyline, just leaving your new curve. Now when we “what” this resultant curve, we get the following:

Now we’ve got something that’s a degree 3 curve that passes through the points of our ordinate file, so this must be great, right? Well there’s three problems with this, one minor and two major. First, the minor one – look closely at the trailing edge.

Well that’s not right, but it’s certainly fixable – like I said, a minor issue. Now for my big problems with this method. As I said at the top, an airfoil is a thickness distribution, often combined with a camber deflection. Those should be SMOOTH functions. Adding them together should make something SMOOTH. Especially for those of us making composite structures, we’d like to be as close to that Class-A surface ideal as possible. Rhino has a great tool for analyzing the smoothness of surfaces and curves – it’s called CurvatureGraph. So let’s look at the curvature graph for this airfoil:

Well. That looks awful. I mean really! Think about it, if you’re going to create a wing or tail surface using this curve as an input, and then you try to make a blend or fillet from that surface, how can you really expect that blend to be smooth? Before T-Splines, I would make most of my blends between surfaces using NetworkSrf. It’s a great tool, allowing you to dial in position/tangency/curvature along each edge of the blend. But how can you possibly expect to create a nice blend that matches the curvature of your flying surface, if the curvature of your flying surface looks like this? So that’s big problem one. Big problem two concerns the density of this curve. Do you really think you need ~250 points to accurately describe an airfoil using a degree 3 curve? I’m just going to come out and say that no, you don’t. That’s far far more points than you need. Look at how little is going on in the back half of this airfoil, and yet the control point density looks like this:

There’s barely any curvature in that section, and yet we’ve got tons of control points, making a curve that is too dense to point edit easily, and causing all sorts of problems with our curvature. If we wanted to smooth out our curvature by point editing, where would we even begin? What we effectively have here is an echo of an echo. We’ve taken a mathematical curve, which is smooth, broken it into discrete points, and then fed those points to our modeling software as input for a curve, regardless of the fact that we don’t need all those points to describe a smooth curve.

So that’s the crux of the problem, and here’s how I solve it. Let’s go back to the conceptual level here first. The back half of the airfoil has very little curvature. As you travel from the back along the curve towards the leading edge, the curvature should steadily increase, peaking at the leading edge, then then decreasing as you go back along the other side. So it seems that we would need more control points at the leading edge, and fewer in the back, with a nice smooth transition in control point spacing between the two. If we were to simply “Rebuild” this curve using the standard Rhino Rebuild command, the point spacing would be even, which means in order to fit the leading edge nicely, we would again end up with too many points at the trailing edge. This is because when Rhino rebuilds a curve, it divides the curve evenly into however many control points you specify. So we need to come up with some other way of dividing up our curve, in a way that is not a linear spacing. The term for what we want is cosine spacing. The best way for me to describe it is graphically:

Instead of dividing the line by an even length of segments, we’ve used an arc that spans the curve which has been divided equally, and then projected THOSE points onto the curve. What you see here is referred to as full cosine spacing – the curve start and curve end both have tightly clustered points with wider spacing in the middle. There’s another option, which is half cosine spacing, and that looks like this:

Okay, so if we’re dealing with a straight line, we can certainly graphically cosine space a line, but that does very little for us if we want to cosine space a curve, since no command exists in Rhino to cosine space a curve. What’s the solution? Well all you need to do is download my handy cosine spacing plugin for Rhino. Okay, so now we can divide our airfoil into a cosine spaced curve, which is how our control points should be spaced. But, before we do it, remember we want our point of maximum curvature to be right at the leading edge. So if we were to simply cosine space our airfoil as is, there would be no way to make sure you have a control point right at the leading edge. So, let’s break the airfoil into a top and bottom curve, and then half cosine space each of those. Make a layer called Cosine Spaced, split your Interp Crv into two halves, and then check the direction of the curves using dir. Make sure the direction of your curves looks like this:

Now run the CosSpacing command to divide up your curve. Which brings us to an important point. How many segments? Well, if you’re using Rhino or other standard NURBS software, it all comes down to how many points you need to properly fit your cosine spaced curve to your “reference” airfoil. If you’re using T-Splines, this is actually a very critical question. For reasons which I will outline in my April 26th webcast hosted by T-Splines, it is critical to maintaining the accuracy of your airfoils to use a power of 2 for the number of segments for both the top and bottom, and that you should of course have the same number on top as on the bottom, regardless of whether your airfoil is symmetrical or not. I have found that for tail airfoils, I can typically get the level of accuracy I want using 16 segments and for wings I typically need 32 segments. This is because the chord length of my tails is less than that of wings, and so fewer points are needed on the tail to maintain the absolute accuracy I’m looking for. If you’re using Rhino or another surface modeling package, I would kindly suggest that you use the same power of 2 rule, so that if you ever end up using T-Splines, or are sharing your airfoils with someone who does (ahem, me), they do not have to be redrawn. Here’s how it looks with your InterpCrv divided up using 16 half cosine spaced segments (17 points per side) on the top and bottom surface:

So now conceptually, we have what we want – more control points at the leading edge, fewer at the trailing edge, and a nice smooth transition between the two. Now got to Curve->Free-Form->Interpolate Points. Starting from the trailing edge, go around the airfoil using the cosine spaced points as your input. When you get back to the trailing edge, you’ll see that it wants to close the curve smoothly at the trailing edge, which of course you don’t want. Just toggle Sharp to Yes, and it will give you that nice crisp trailing edge. Turn the PointsOn and see what you’ve got:

Notice that it inserted two control points between the trailing edge point and the points closest to the trailing edge. Delete those to maintain your original point/segment count. Now you’ve got to see how close your new airfoil is to your reference airfoil. Run CrvDeviation to test this:

For a 20″ chord length, we have a maximum deviation of .0035″, and it occurs at about the 95% chord location. I’ll take that. Now let’s look at the curvature graph:

This is a VAST improvement over the traditional method. Notice how few kinks there are in the curvature, and how the curvature along the back half of the airfoil stays relatively constant – as it should – instead of wavering back and forth like it did on the previous method. We’ve also thinned out the number of control points from around 260 to 33, a reduction of 87%. This is a far easier airfoil to deal with, and the smoother curvature will helpful in creating blends and fillets off of the wings and tails you make from these airfoils. If you’re going to use this airfoil in a T-Spline model, the only thing left is to ExtractControlPolygon to get something that you can use tsExtrude to create your wing/tail. That would look like this:

I believe that this method is a significant improvement over the status quo, and I hope you find it useful and helpful in your own projects. If you’d like to download the Rhino file used for this demo, you can do so here.

A few notes in closing. You might be wondering how this method deals with cusped airfoils, since there will be some increase in curvature at the trailing edge. I have found that if you’re using 32 control points for a cusped wing airfoil, the density at the trailing edge is sufficient to match the reference airfoil. Also, I mentioned at the top that you could take this airfoil and easily create thicker or thinner versions of it. Just use Scale1D to do so. If you want to create a NACA 0012 airfoil, you can do so by simply scaling 1D in the y axis by 1.2. Just like this:

Comments

Thank you for creating and pioneering these techniques! Thank you for the accompanying plug-in as well.

Not quite clear to me whether the Sharp selection applied at the trailing edge results in an infinitely sharp edge? Or if, as discussed in the introductory paragraphs, it this TE has real world thickness in Rhino?

It appears that maybe the plug-in, applied to the split airfoil, might create superimposed control points at the beginning and end of each half-airfoil? Is this the case and if so, does it matter at all?

Thank you for your clear insights — a real breath of fresh air in what seems to me a deeply muddled area of CAD design. I am looking forward to seeing the webinar.

You are right that the Cosine Spacing plugin will create duplicate points at the leading and trailing edge. This is because unlike the Rhino divide commands, it does not have the ability to not mark the curve ends. Perhaps when I have my friend update the function I will have him add that. As you suggested, it does not matter one bit as long as you are o-snapping to the points, since the points are identical. I will post an update in a day or two talking about how to best deal with finite thickness trailing edges – you are correct that the example here is for infinitely sharp. Thanks! -Sky

My sincere and deep congratulations about the TSplines webinar, it was sharp, clear, focused point and very cool.
The Cosine Spacing methodology is an example of clever use of maths for solve distributions problems.
I encourage you to keep going on.

Thanks for sharing this. I think taking the step into .dxf is a mistake however. I have always found importing dxf files to be inaccurate for whatever reason, probably the lack of a recognized standard definition of the file format so they vary a lot.

Also, Profili will give you a reasonable points file if you just ask it to, so you don’t get >200 points. I don’t know how the format is standardized, but most point files for airfoils provide better definition around the highly curved parts. These point files are obviously widely available and importable to Profili.

In Profili go “Airfoils>airfoils management”, select your airfoil, modify the trailing edge/camber/thickness and analyze as appropriate (yes the method of trailing edge modification affects the performance a bit), then “Export>export to txt”. You can also use .dat or .csv – Rhino handles them all.

Then in Rhino, “Import”, select the file, use tab/comma/space delimited and the plane/origin/rotate/scale options as appropriate. Usually Rhino picks the proper delimiter.

Right click the icon for “curve thru points”, select points in order; top trailing around the front to bottom trailing, then close with a line across the trailing edge. The airfoil I just tried gave me 31 points top and bottom, spaced appropriately.The “what” command reports NURBS curve. Of course if you left click the curve tool icon you get a control point curve which is not at all what you want. I don’t see much point in checking the curvature as the points define the airfoil – pretty direct as long as you draw the proper type of curve through them.

That’s it. Maybe I am missing something you are doing with the dxf, but it seems to create more problems than it solves.

Really enjoying the gear pants stuff; you almost have me looking at T-splines but I can’t explain why just yet. Seems more useful for the reverse engineering stuff than forward modeling.

Thanks so much for your thoughtful reply. I’m in Kathmandu right now, and typing this on an iPad, so my response may be a bit more brief than typial. I’m simply using dxf as a transfer method from Profili to Rhino, but you’re right I could just use csv or something like that. Probably fewer clicks in Profili to boot. I have not experienced any kind of inaccuracies from dxf transfers, but I’m interested in doing a point by point comparison when I get home. The data SHOULD be identical, but should and is can be two different things.

Really what I’m doing with this method is drawing the airfoil with as few points as possible, with a known deviation from the “reference” airfoil. The thinking is really along the lines of how a class A surface modeler must think to create the highest surface quality possible. My only concern with your method is that I’m not sure how Profili is interpolating the airfoil surface between the known points – do you? Doing it in Rhino also allows for the greatest control over the location of control points – if I need to I can point edit the resultant NURBS curve to fit the reference airfoil even better. So if I had to sum it all up, to answer your “why bother with doing this in Rhino” question, it all comes down to being able to create a degree 3 airfoil with as few points as possible, so that when I go and use this airfoil to make a class A surface model, my life is much much easier. This is especially true with T-Splines – since a T-Spline model is unified, the airfoil geometry must flow into any joining surfaces, and therefore should be as “light” as possible.

T-Splines is wonderful for both concept design and reverse engineering. You should give it a try!

Profili uses cubic splines to interpolate points, which is actually done in XFOIL. I have no idea how it generates a dxf file or what the tolerance of that file would be to the points file.

I understand why one needs to get an airfoil into Rhino; I do that a lot. But importing points and fitting a curve in Rhino has to be more bombproof than generating a dxf and importing that.

Basically I just wanted to point out that most airfoil point files already have points distributed the way you describe, and you can import them to Rhino directly. For the point files that have few points around leading edge (some Eppler sections and others) XFOIL has a nice interpolation function to provide extra data points. This saves doing point projection in Rhino also.

I guess I would never move any of the points around in Rhino, because they are pretty much the gold standard. To test one could import a dxf to Rhino, then import points from Profili and see how close they are to the curve. I’m guessing pretty close, but then you have to consider that not all CAD programs use the same dxf format and one can get some weird distortions without realizing it or being able to predict it. That is all I’m trying to point out (pardon the pun).

You bring up some interesting points, certainly worthy of some experimentation. Just got home from Nepal, brain feeling like jelly, but I’m sure I’ll be up at 3 am needing something to do, so I’ll play around with some of the scenarios you suggest and let you know what I find.

I haven’t forgotten about this, just been busy with other projects. I have however tested out your theory that Profili is somehow distorting the dxf output of the ordinate files, and have found this to not be the case. I spit out several dxf files at 100 inch chord lengths, and compared them to the imported .txt file. Just by eye, the points of the point cloud lined up exactly on top of the verticies of the degree 1 polyline. I then exploded the point cloud that was the result of the txt import, and then used PointDeviation to test the difference between the points and the polyline. The deviation was less than 0.00001″, which is an order of magnitude less than the precision of the coordinate files (4 decimal places). So, in short, no, there is no distortion occurring when you export as a dxf from Profili.

Yup! Do you need help getting it working? I’m using Rhino5 32 bit, not 64. The current version of madCAM works just fine in 32 bit, but not 64. That’s the only thing keeping me from using Rhino5/64 full time.