5 views (last 30 days)

Hello,

i have a bunch of lift cs. drag polars with fixed speed. Now i want to create an interpolated polar at a certain speed between two of them. Is there any built in function in Matlab to achieve this? I dont know how to do it with the interp functions.

John D'Errico
on 21 Sep 2020

Edited: John D'Errico
on 21 Sep 2020

You don't provide the actual data. But you are asking to do something which is trivially easy for the eye to do, more difficult for the computer.

This is not a question of linearly interpolating the two curves. It is of finding a sequence of midpoints that are visually midway between the curves, thus equidistant. But what is the distance between two curves? How will you define that distance?

In fact, this is a difficult problem. Consider two nonlinear curves, I'll call them A and B. Given any pooint on A, we might decide to find the closest point on curve B, then take the midpoint of the resulting line segment. The problem is, If we had started with the SAME point on curve B, and then found the closest point on curve A? It need not necessarily be the original point!

Do you see that the act of finding the closest point on a curve is not a commutative operator? That very claim means finding the midpoint between two curves is not a trivial task.

Regardless, that is how I would solve your problem. Given curves A and B, I would start with a sequence of points on curve A. For each such point, I would find the closest point on curve B. Then find the midpoint of each line segment. Use that as your mid-curve.

If I wanted to improve this scheme, I might then start with a similar sequence of points on curve B, now finding the sequence of closest points on curve A. Again, find the midpoint of each line segment. As I said, these two operations will generally NOT result in the same mid-curve! The two curves may be reasonably close though, at least if A and B are not too noisy.

Finally, though I would repeat the process, now finding the mid-curve between each of the last two curves. This iterative scheme should eventually approach a happy medium.

The nice thing is, you can do it all using two simple functions I have provided on the file exchange - distance2curve and interparc. (I'll get links for them in a second.)

First, an example. Two simple curves, since I lack your data.

x1 = linspace(-1,1,20);

F1 = @(x) 0.1*x.^3 + x.^2 + 1;

y1 = F1(x1);

x2 = linspace(-1.1,1.2,15);

F2 = @(x) 1.1 - cos(x);

y2 = F2(x2);

plot(x1,y1,'r-o',x2,y2,'bs--')

legend(func2str(F1),func2str(F2))

So two curves, sampled at a different number of points, not even over the same domain. And that means finding the mid-curve will be far more difficult than just interpolating the two curves at a list of points. Had I made the two curves such that they were not even single valued functions, it would be more difficult yet.

Finding the mid-curve between the two curves is not something as simple as just finding the average of the two curves, not in any respect. And it is NOT something that simple interpolation can handle. Interp1 would fail, for example, on the curves drawn in your figure, since they are not single-valued functions of x.

So how would I treat this?

First, I would choose a sequence of points equally spaced along curve 1. My interparc utility will do that nicely.

Then find the closest point for each on curve 2 for every such point from the first step. Find the midpoint of each indicated line segment between the two curves.

Repeat the process, starting with points on curve 2, finding the closest point on curve 1.

Finally, I'll draw the two mid-curves. We can see if they are reasonably close to being the same. If not, then we might consider repeating the process.

I'll write the entire thing as a function, since we will need to do it more than once.

function xymid = midcurve(xref,yref,xtarg,ytarg,n)

% two curves, one called the reference curve, the other the target.

% n is the number of points to generate along the reference curve.

% in come cases, there may be one or two more points appended to the

% ends of the mid curve. So the resulting curve may have n, n+1, or n+2

% total points on the curve.

% interpolate n points, equidistant on the reference curve.

xyrefint = interparc(n,xref,yref,'spline');

% For each of those points, find the CLOSEST point on the target curve.

[xytargint,D] = distance2curve([xtarg(:),ytarg(:)],xyrefint,'spline');

% get a measure of the overall distance between the two curves, to

% create a tolerance for the final step.

tol = mean(D)*1e-14;

% find the midpoint of each line segment connecting the curves

xymid = (xyrefint + xytargint)/2;

% was the first point the average of the first two points form the target

% and reference curves? If not, then extend the mid-curve by one point.

% Do so at each end if necessary.

if norm(xymid(1,:) - [(xref(1) + xtarg(1))/2,(yref(1) + ytarg(1))/2]) > tol

% appending a point at the start of the curve.

xymid = [(xref(1) + xtarg(1))/2,(yref(1) + ytarg(1))/2;xymid];

end

if norm(xymid(end,:) - [(xref(end) + xtarg(end))/2,(yref(end) + ytarg(end))/2]) > tol

% appending a point at the end of the curve.

xymid = [xymid;(xref(end) + xtarg(end))/2,(yref(end) + ytarg(end))/2];

end

end

That seems to work reasonably well. I have verified that if I swap the reference and target curves for the process, I do get subtly different results, but the distinction is not immense. Of course, these two test curves were not too nasty in shape.

xymid12 = midcurve(x1,y1,x2,y2,50);

xymid21 = midcurve(x2,y2,x1,y1,50);

plot(x1,y1,'k-o',x2,y2,'k-o',xymid12(:,1),xymid12(:,2),'ro-',xymid21(:,1),xymid21(:,2),'gs--')

So I did get two subtly different mid-curves. Not too bad. I could repeat the process with those two curves and it would quickly converge.

Find the tools distance2curve and interparc on the file exchange, here:

So in the end, not too difficult. It took some care in the writing, but almost all of the work was done in my two utilities, so I had to write relatively little new code.

Ameer Hamza
on 21 Sep 2020

Check this code

% generating curves

x = linspace(1, 2, 100);

y1 = x.^3 + 2 + rand(size(x))*0.1; % let t=10 for this curve

y2 = x.^2 + 1 + rand(size(x))*0.1; % let t=15 for this curve

Y = [y1(:) y2(:)].';

ym = interp1([10 15], Y, 12); % interpolate at t=12

plot(x, y1, 'b-', x, y2, 'r-', x, ym, 'k--');

Image Analyst
on 21 Sep 2020

Since the blue and yellow x,y vectors may not be the same length, you can't simply use interp1(). An approach I think might work is to use a scatteredInterpolant (demo attached). Another way might be to scan one vector, finding the closest point in the other vector and then take the midpoint.

Attach your data if you want more help.

Opportunities for recent engineering grads.

Apply TodayFind the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
## 2 Comments

## Direct link to this comment

https://de.mathworks.com/matlabcentral/answers/597199-how-can-i-compute-an-interpolated-curve#comment_1017604

⋮## Direct link to this comment

https://de.mathworks.com/matlabcentral/answers/597199-how-can-i-compute-an-interpolated-curve#comment_1017604

## Direct link to this comment

https://de.mathworks.com/matlabcentral/answers/597199-how-can-i-compute-an-interpolated-curve#comment_1017625

⋮## Direct link to this comment

https://de.mathworks.com/matlabcentral/answers/597199-how-can-i-compute-an-interpolated-curve#comment_1017625

Sign in to comment.