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:
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:
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:
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: