Why is ScatteredInterpolant (linear) returning a value far outside of input data?

27 Ansichten (letzte 30 Tage)
So I'm using ScatteredInterpolant to interpolate the values of a measurement on the surface of a helicopter blade. I'm showing it graphically in the figure. The input data is shown with the faint lines at a 45 degree angle. The output is the coloring of the surface. Right in the center is a bright spot. The highest input data value is ~119. The output value at that location is about 2512.
I've attached the data which generated that figure. The function used to generate the Interpolation is:
Interpolant = scatteredInterpolant(inX, inY, inZ, inV,'linear','nearest');
outV = Interpolant(outX, outY, outZ);
For reference, the bad output data point is the 2713 entry in outV. How can I possibly get an output value that is more than an order of magnitude bigger than any input value, when using linear interpolation? Is this a bug?
A quick way to visualize the error:
figure;
plot3(inX, inY, inV, 'o');
hold on
plot3(outX, outY, outV, 'o');
  4 Kommentare
Jason Whitfield
Jason Whitfield am 28 Jun. 2018
I've attached the results I get by running the following code.
clear;
load('failingData.mat');
outV = Interpolant(outX, outY, outZ);
The outV data looks good to me. I'm not sure why you're getting a different result.
Dan K.
Dan K. am 29 Jun. 2018
Yes, I see that you get good looking results, but when I execute the exact same code, I get the values of outV you see in the plot above. I've submitted a bug report to TMW, and I'll post an update if I find out more.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

John D'Errico
John D'Errico am 28 Jun. 2018
Bearbeitet: John D'Errico am 28 Jun. 2018
You are making a major error here in what you are trying to do.
plot3(inX,inY,inZ,'bo')
box on
grid on
Now, rotated one way, we see this surface.
Now, rotated slightly differently, we see this:
So you have essentially a nice surface in 2-dimensions. But there is NO information about what happens when you move off that surface. Now, add in the points you are trying to "interpolate".
hold on
plot3(outX,outY,outZ,'r+')
Yep. You are trying to predict values that lie HUGELY away from the 2-manifold of data that you have. Massive extrapolation here.
So, regardless of what scatteredInterpolant did, your results will be complete, meaningless garbage. You don't have three independent variables, comprising a true point cloud. You have a 2-manifold of data.
So what will scatteredInterpolant try to do here? Linear interpolation for any point will involve a tessellation of that domain. It will not be some sort of triangulation of the surface, but a set of tetrahedra spanning, dissecting that domain. At each of those points, you have a value of V that you wish to interpolate.
So scatteredInterpolant uses a tessellation of that domain. Thinking that you have a real point cloud.
tess = delaunayn([inX,inY,inZ]);
whos tess
Name Size Bytes Class Attributes
tess 43112x4 1379584 double
So there are 43112 tetrahedra. Its kind of hard to visualize, since there are so many edges. But the volume looks like this:
Most of those tetrahedra are HUGE things. Spanning across that void where no data exists. scatteredInterpolant has no clue what you did. At any poiint in that domain, it finds the tretrahedron that contains your point. Then it does LINEAR interpolation across that tetrahedron. But remember that most of the tetrahedra are huge things, connecting one "wing" of that surface with the other. (No pun intended with use of the word wing here, on what is essentially airfoil data.)
ScatteredInterpolant just does what it is told, having no idea that when you try to interpolate some point in that volume, it is creating meaningless gibberish as a result. I'm sorry, but you simply cannot use scatteredInterpolant to produce a meaningful result from this data, as you are trying to do.
Do I really need to figure out why you got something mildly strange? Garbage in, garbage out. I guess I could go a bit more deeply into what you have, if you really want it. But it would be a pure exercise in trying to debug code that I don't have, because as I recall, scatteredInterpolant is supplied to us in compiled form.
  7 Kommentare
John D'Errico
John D'Errico am 2 Jul. 2018
Bearbeitet: John D'Errico am 2 Jul. 2018
You can't do that, at least not easily tell MATLAB that an arbitrary triangulated 2-manifold could be viewed as some sort of regularly gridded surface.
If, however, you have a triangulated surface, then the answer is easy enough. Some years ago, I wrote closestmanifoldpoint.m.
Given a triangulation and a list of points in 3-dimensions, it finds the simplex which lies closest to each point. It returns a set of barycentric coordinates inside that simplex, used for interpolation. But if you supply information about any mapping, defined at each node of the triangulation, it also does the interpolation for you.
It is part of a larger set of tools, but simply used without them.
You will need to define a struct to pass in the information about the triangulation. The second argument, sc must be a struct with three fields, sc.domain, sc.tessellation, and sc.range.
The domain field will be a list of points in R^3, one point per row, so the list of vertices of the triangulation. So sc.domain must be an NPx3 array, assuming NP nodes in the triangulation.
sc.tessellation will be an NTx3 array, listing the connectivity for each triangle in the surface, so relative references to the rows of the domain.
Finally, this code can also do interpolation as I said. That is accomplished by having a range field in the struct. The range field must be of size NPxk, where each column of this array is a variable to be interpolated. Assuming you are just using this to predict one value at each point, the range field will be a vector, of size NPx1.
Call it like this:
[x,dx,whichsimplex,bcc,rangeInterp] = closestmanifoldpoint(X,sc);
where X is an array of points to be mapped to the surface, and then interpolated.
So all you need to do is supply a triangulation. I've attached closestmanifoldpoint, as well as the only subordinate function that I noticed, rowspaces.
For example, here is a simplicial complex struct that defines a triangulation of the surface of a unit sphere.
sc
sc =
struct with fields:
domain: [62×3 double]
tessellation: [120×3 double]
range: [62×1 double]
The color coding in that figure comes from the range field, which I generated as a uniform random variable, rand(62,1). Not very creative, I know.
[x,dx,whichsimplex,bcc,rangeInterp] = closestmanifoldpoint(rand(10,3),sc);
rangeInterp
rangeInterp =
0.592628927726262
0.329792850128984
0.368604533985401
0.633207288915207
0.325491526196841
0.278335770755433
0.3232807215718
0.469008085876214
0.409532773231336
0.656797929332787
So, given a set of random points in the unit cube, it found the closest point on that surface, then did an interpolation. Yeah, its random garbage here, but only because of the intensely creative way I created the vector to fill in that range field.
That means your problem just got very easy to solve, as long as you have the triangulation defining that surface manifold. And, because I wrote the code, I do know what it does.
Dan K.
Dan K. am 3 Jul. 2018
Bearbeitet: Dan K. am 3 Jul. 2018
Wow... John, thank you so much for your help. I'm still working on the details of how to implement it, since the triangulation I have is for the query points, not the data points (as you've shown in your example). But thank you.
Dan
Following up... I had an idea that I think should work, but I figured I would run it past you to see if you think I'm nuts.
What I'm ultimately trying to do is to interpolate the in-plane strain measurement on the surface of my blade. So what I'm thinking is trying to do this:
Since my blade is mostly just a uniform extrusion of a single cross section (i.e. the manifold) I should be able to map any point on the blade (except for the tapered ends) onto a 2 dimensional plane by "unrolling it". What I'm envisioning here is if I could cut the blade along its trailing edge and iron it flat, then I would have a single sheet that has all the measurements in plane. Then I do my interpolation, in-plane, using the 2D version of scattered Interpolant, and then remap it back onto the 3D geometry of the original blade.
So if I start with the original blade geometry showing all my data points.
I can do the mapping by keeping the Y value the same (i.e. distance down the blade), and for each data point I determine the equivalent XX location which is the distance around the blade from the trailing edge, using something like your arclength function. I know the cross section of the blade, so I can snap each data point's X-Z value onto the cross section and integrate distance around the perimeter to create my data map in the new XX-Y coordinate system.
I do the same thing with my query points, keeping track of each query point's mapping from X-Y-Z into XX-Y. Then do the interpolation in the XX-Y domain, and assign the value back to that query point's original X-Y-Z coordinates.
Naturally, I can't do this at the ends of the blade where my XX-Y plane projection would be distorted, but I don't actually have any data there.
Does this make sense?
Thanks, Dan

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte


Version

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by