How to represent [airfoil] coordinates as a polynomial
Show older comments
I am creating some code that allows the user to input a file containing airfoil coordinates ( :,1) = x coordinates, ( :,2) = y coordinates. Below are the coordinates for the upper surface of the airfoil (Leading edge to Trailing edge)
0 0
0.00369000000000000 0.0134500000000000
0.0170200000000000 0.0280700000000000
0.0336900000000000 0.0390000000000000
0.0515300000000000 0.0479600000000000
0.0699500000000000 0.0556700000000000
0.107870000000000 0.0682100000000000
0.127140000000000 0.0734700000000000
0.146570000000000 0.0781200000000000
0.166120000000000 0.0822000000000000
0.185780000000000 0.0857400000000000
0.205520000000000 0.0888000000000000
0.225320000000000 0.0914200000000000
0.245170000000000 0.0936200000000000
0.265070000000000 0.0954000000000000
0.284990000000000 0.0968000000000000
0.304940000000000 0.0978000000000000
0.324910000000000 0.0984500000000000
0.344880000000000 0.0987500000000000
0.364850000000000 0.0987300000000000
0.384830000000000 0.0984200000000000
0.404790000000000 0.0978300000000000
0.424750000000000 0.0969900000000000
0.464630000000000 0.0946300000000000
0.484550000000000 0.0931600000000000
0.504460000000000 0.0915100000000000
0.524350000000000 0.0897100000000000
0.544230000000000 0.0877500000000000
0.564100000000000 0.0856400000000000
0.583940000000000 0.0833600000000000
0.603770000000000 0.0809200000000000
0.623570000000000 0.0783200000000000
0.643360000000000 0.0755700000000000
0.663120000000000 0.0726700000000000
0.682860000000000 0.0696400000000000
0.702590000000000 0.0664700000000000
0.722290000000000 0.0631900000000000
0.741970000000000 0.0597700000000000
0.761630000000000 0.0562300000000000
0.781260000000000 0.0525500000000000
0.800870000000000 0.0487200000000000
0.820450000000000 0.0447600000000000
0.849760000000000 0.0385400000000000
0.869260000000000 0.0342100000000000
0.888730000000000 0.0297500000000000
0.908170000000000 0.0251400000000000
0.927570000000000 0.0204000000000000
0.946930000000000 0.0154900000000000
0.966250000000000 0.0104200000000000
1 0
I would like to be able to represent the curve created by these coordinates as a polynomial so that I can reproduce the curves to a decent degree of accuracy. This must be done as some downloaded airfoils do not contain equal numbers of upper and lower coordinates and I would like to be able to reproduce these airfoils with a user-defined number of x-coordinates ie. (0:0.01:1).
The two main concerns are as follows:
- Input x coordinates are not evenly spaced so polyfit will skew the result as soon as I output it with evenly spaced x coordinates
- First and final coordinates must not change so that any asymmetry/camber can be captured and polyfit fails to conform to this constraint.
Does anyone have any suggestions for a method here?
Accepted Answer
More Answers (2)
Alan Stevens
on 12 Jan 2023
Edited: Alan Stevens
on 12 Jan 2023
How about using a spline fit? After loading your data and calling the first column x and the second column y try
xfit = linspace(0,1,100);
yfit = spline(x,y,xfit);
plot(x,y,'.',xfit,yfit,'o-'),grid
4 Comments
John D'Errico
on 12 Jan 2023
Edited: John D'Errico
on 12 Jan 2023
@Alan Stevens - see the answer I'm writing. Or if you want, just plot the shape of the curve to be fit. Then decide if a spline can represent that curve well. Because splines are still effectively polynomials, they also hate singularities.
That's exactly what I did!
xy = [0 0
0.00369000000000000 0.0134500000000000
0.0170200000000000 0.0280700000000000
0.0336900000000000 0.0390000000000000
0.0515300000000000 0.0479600000000000
0.0699500000000000 0.0556700000000000
0.107870000000000 0.0682100000000000
0.127140000000000 0.0734700000000000
0.146570000000000 0.0781200000000000
0.166120000000000 0.0822000000000000
0.185780000000000 0.0857400000000000
0.205520000000000 0.0888000000000000
0.225320000000000 0.0914200000000000
0.245170000000000 0.0936200000000000
0.265070000000000 0.0954000000000000
0.284990000000000 0.0968000000000000
0.304940000000000 0.0978000000000000
0.324910000000000 0.0984500000000000
0.344880000000000 0.0987500000000000
0.364850000000000 0.0987300000000000
0.384830000000000 0.0984200000000000
0.404790000000000 0.0978300000000000
0.424750000000000 0.0969900000000000
0.464630000000000 0.0946300000000000
0.484550000000000 0.0931600000000000
0.504460000000000 0.0915100000000000
0.524350000000000 0.0897100000000000
0.544230000000000 0.0877500000000000
0.564100000000000 0.0856400000000000
0.583940000000000 0.0833600000000000
0.603770000000000 0.0809200000000000
0.623570000000000 0.0783200000000000
0.643360000000000 0.0755700000000000
0.663120000000000 0.0726700000000000
0.682860000000000 0.0696400000000000
0.702590000000000 0.0664700000000000
0.722290000000000 0.0631900000000000
0.741970000000000 0.0597700000000000
0.761630000000000 0.0562300000000000
0.781260000000000 0.0525500000000000
0.800870000000000 0.0487200000000000
0.820450000000000 0.0447600000000000
0.849760000000000 0.0385400000000000
0.869260000000000 0.0342100000000000
0.888730000000000 0.0297500000000000
0.908170000000000 0.0251400000000000
0.927570000000000 0.0204000000000000
0.946930000000000 0.0154900000000000
0.966250000000000 0.0104200000000000
1 0];
x = xy(:,1);
y = xy(:,2);
xfit = linspace(0,1,100);
yfit = spline(x,y,xfit);
plot(x,y,'.',xfit,yfit,'o-'),grid
Not perfect, but better than a polynomial fit.
John D'Errico
on 12 Jan 2023
Edited: John D'Errico
on 12 Jan 2023
Not really. Again. LOOK VERY CAREFULLY NEAR ZERO. Do you see the strange bend there?
Check out my answer, as I have now finished it. It explains why a spline fails at zero. Yes, it does better than a normal polynomial. And I'll admit a spline model is decent there. And a spline does go exactly through the points, so that is a virtue.
John D'Errico
on 12 Jan 2023
Edited: John D'Errico
on 12 Jan 2023
Ok. Let me suggest, that HAD you build a subtly different model, much of the form I built, a spline would have been perfectly adequate. For example, try this:
xy = [0 0
0.00369000000000000 0.0134500000000000
0.0170200000000000 0.0280700000000000
0.0336900000000000 0.0390000000000000
0.0515300000000000 0.0479600000000000
0.0699500000000000 0.0556700000000000
0.107870000000000 0.0682100000000000
0.127140000000000 0.0734700000000000
0.146570000000000 0.0781200000000000
0.166120000000000 0.0822000000000000
0.185780000000000 0.0857400000000000
0.205520000000000 0.0888000000000000
0.225320000000000 0.0914200000000000
0.245170000000000 0.0936200000000000
0.265070000000000 0.0954000000000000
0.284990000000000 0.0968000000000000
0.304940000000000 0.0978000000000000
0.324910000000000 0.0984500000000000
0.344880000000000 0.0987500000000000
0.364850000000000 0.0987300000000000
0.384830000000000 0.0984200000000000
0.404790000000000 0.0978300000000000
0.424750000000000 0.0969900000000000
0.464630000000000 0.0946300000000000
0.484550000000000 0.0931600000000000
0.504460000000000 0.0915100000000000
0.524350000000000 0.0897100000000000
0.544230000000000 0.0877500000000000
0.564100000000000 0.0856400000000000
0.583940000000000 0.0833600000000000
0.603770000000000 0.0809200000000000
0.623570000000000 0.0783200000000000
0.643360000000000 0.0755700000000000
0.663120000000000 0.0726700000000000
0.682860000000000 0.0696400000000000
0.702590000000000 0.0664700000000000
0.722290000000000 0.0631900000000000
0.741970000000000 0.0597700000000000
0.761630000000000 0.0562300000000000
0.781260000000000 0.0525500000000000
0.800870000000000 0.0487200000000000
0.820450000000000 0.0447600000000000
0.849760000000000 0.0385400000000000
0.869260000000000 0.0342100000000000
0.888730000000000 0.0297500000000000
0.908170000000000 0.0251400000000000
0.927570000000000 0.0204000000000000
0.946930000000000 0.0154900000000000
0.966250000000000 0.0104200000000000
1 0];
x = xy(:,1);
y = xy(:,2);
spl = spline(x(2:end),y(2:end)./sqrt(x(2:end)));
fun = @(x) sqrt(x).*fnval(spl,x);
fplot(fun,[0,.1],'r-')
hold on
plot(x(1:7),y(1:7),'bo')
That would be a model that has the necessary behaviors at each end point, AND uses a spline. In fact, the resulting curve is actually better than mine in a sense, because it passes exactly through all of the data points, rather than being a least squares fit as I used. The important point is a spline does not perform well when you have a singularity in the curve.
Bruno Luong
on 12 Jan 2023
Edited: Bruno Luong
on 12 Jan 2023
You could use the free-knot spline
xy = [0 0
0.00369000000000000 0.0134500000000000
0.0170200000000000 0.0280700000000000
0.0336900000000000 0.0390000000000000
0.0515300000000000 0.0479600000000000
0.0699500000000000 0.0556700000000000
0.107870000000000 0.0682100000000000
0.127140000000000 0.0734700000000000
0.146570000000000 0.0781200000000000
0.166120000000000 0.0822000000000000
0.185780000000000 0.0857400000000000
0.205520000000000 0.0888000000000000
0.225320000000000 0.0914200000000000
0.245170000000000 0.0936200000000000
0.265070000000000 0.0954000000000000
0.284990000000000 0.0968000000000000
0.304940000000000 0.0978000000000000
0.324910000000000 0.0984500000000000
0.344880000000000 0.0987500000000000
0.364850000000000 0.0987300000000000
0.384830000000000 0.0984200000000000
0.404790000000000 0.0978300000000000
0.424750000000000 0.0969900000000000
0.464630000000000 0.0946300000000000
0.484550000000000 0.0931600000000000
0.504460000000000 0.0915100000000000
0.524350000000000 0.0897100000000000
0.544230000000000 0.0877500000000000
0.564100000000000 0.0856400000000000
0.583940000000000 0.0833600000000000
0.603770000000000 0.0809200000000000
0.623570000000000 0.0783200000000000
0.643360000000000 0.0755700000000000
0.663120000000000 0.0726700000000000
0.682860000000000 0.0696400000000000
0.702590000000000 0.0664700000000000
0.722290000000000 0.0631900000000000
0.741970000000000 0.0597700000000000
0.761630000000000 0.0562300000000000
0.781260000000000 0.0525500000000000
0.800870000000000 0.0487200000000000
0.820450000000000 0.0447600000000000
0.849760000000000 0.0385400000000000
0.869260000000000 0.0342100000000000
0.888730000000000 0.0297500000000000
0.908170000000000 0.0251400000000000
0.927570000000000 0.0204000000000000
0.946930000000000 0.0154900000000000
0.966250000000000 0.0104200000000000
1 0];
x = xy(:,1);
y = xy(:,2);
pp=BSFK(x,y); % https://fr.mathworks.com/matlabcentral/fileexchange/25872-free-knot-spline-approximation
foilfun = @(x) ppval(pp,x);
xi = linspace(0,1,501);
close all
plot(x,y,'or',xi,foilfun(xi),'b-')

Categories
Find more on Spline Postprocessing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



