You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi @DanielVandH, I absolute love this package well done!. I think it is vital for geometry processing etc and for scattered data interpolation/extrapolation.
I've tested this package and it works really well when interpolating well within the convexhull. And when I say "well within" I suppose that means for regions with a lot of points surrounding them rather than at the boundary.
Here is a screenshot of the performance of the various methods where I test it very much like your demo in the README but with non-gridded (random) data point input:
It looks like at the boundary we snap to a kind of "nearest neighbour/linear extrapolation origami". There are clear creases and kinks and it seems that this doesn't just happen outside of the convex hull but also just at the boundary (see the kinks starting inside the convex hull e.g. at the top corner). I suspect there are two things going on here. 1) you probably switch method for extrapolation, and 2) perhaps there are to few points at the boundary to enforce the smoothness. Would it help to reflect points out at the boundary so the local slopes continue and additional fictitious data is provided. Or is there another way, especially for the smoother methods, to make the behaviour at the boundaries more consistent with the otherwise C1/ C2 continuous nature of them?
naturalNeighbourInterp.mp4
Thanks!
For completeness, here is the code I used:
using GLMakie
using GLMakie.GeometryBasics
using NaturalNeighbours
using StableRNGs
f = (x, y) ->sin(x * y) -cos(x - y) *exp(-(x - y)^2)
numPointsData =100
rng =StableRNG(123)
x =rand(rng, numPointsData)
y =rand(rng, numPointsData)
z =f.(x,y)
itp =interpolate(x,y, z; derivatives=true)
numPointsInterp =100
x_i_r =range(0.0, 1.0, numPointsInterp)
y_i_r =range(0.0, 1.0, numPointsInterp)
functionpointGrid(x_i_r, y_i_r)
x_i =Vector{Float64}(undef,numPointsInterp^2)
y_i =Vector{Float64}(undef,numPointsInterp^2)
i =1for y in y_i_r
for x in x_i_r
x_i[i] = x
y_i[i] = y
i+=1endendreturn x_i, y_i
end
x_i, y_i =pointGrid(x_i_r, y_i_r)
methodSet = (NaturalNeighbours.Sibson(),
NaturalNeighbours.Triangle(),
NaturalNeighbours.Laplace(),
NaturalNeighbours.Sibson(1),
NaturalNeighbours.Nearest(),
NaturalNeighbours.Farin(),
NaturalNeighbours.Hiyoshi(1),
NaturalNeighbours.Hiyoshi(2)
)
titleStrings = ("Sibson", "Triangle", "Laplace", "Sibson(1)", "Nearest", "Farin", "Hiyoshi(1)", "Hiyoshi(2)")
fig =Figure(size = (800,800))
V = [Point{3,Float64}(x[i], y[i], z[i]) for i ineachindex(x)]
functiontoquadmesh(V, numRows)
numCols =length(V)/numRows # Number of point "columns"if!isinteger(numCols) || numCols<1throw(ArgumentError("The length(V)/numRows should produce an integer >1 but is instead $numCols"))
end
numCols =Int(numCols)
ij2ind(i,j) = i + numCols*(j-1) # function to convert subscript to linear indices
F =Vector{QuadFace{Int}}(undef,(numCols-1)*(numRows-1))
i_f =1@inboundsfor i =1:(numCols-1)
@inboundsfor j =1:(numRows-1)
F[i_f] =QuadFace{Int}(ij2ind(i,j),
ij2ind(mod1(i+1,numCols), j),
ij2ind(mod1(i+1,numCols), mod1(j+1,numRows)),
ij2ind(i,mod1(j+1,numRows)))
i_f +=1endendreturn F
endfor testCase =1:1:length(methodSet)
methodNow = methodSet[testCase]
z_i =itp(x_i,y_i; method=methodNow)
V_i = [Point{3,Float64}(x_i[i], y_i[i], z_i[i]) for i ineachindex(x_i)]
if testCase<=4
r =1
c = testCase
else
r =2
c = testCase-4end
F_i =toquadmesh(V_i, numPointsInterp)
ax =Axis3(fig[r, c], clip=false, viewmode =:free, aspect =:data, xlabel ="X", ylabel ="Y", zlabel ="Z", title="method: "* titleStrings[testCase])
hp1 =scatter!(ax, V, markersize=12, color=:black)
# hp2 = scatter!(ax, V_i, markersize=8, color=:red)
hp3 =mesh!(ax, GLMakie.GeometryBasics.Mesh(V_i,F_i), color=z_i)
end
fig
Hi @DanielVandH, I absolute love this package well done!. I think it is vital for geometry processing etc and for scattered data interpolation/extrapolation.
I've tested this package and it works really well when interpolating well within the convexhull. And when I say "well within" I suppose that means for regions with a lot of points surrounding them rather than at the boundary.
Here is a screenshot of the performance of the various methods where I test it very much like your demo in the README but with non-gridded (random) data point input:

It looks like at the boundary we snap to a kind of "nearest neighbour/linear extrapolation origami". There are clear creases and kinks and it seems that this doesn't just happen outside of the convex hull but also just at the boundary (see the kinks starting inside the convex hull e.g. at the top corner). I suspect there are two things going on here. 1) you probably switch method for extrapolation, and 2) perhaps there are to few points at the boundary to enforce the smoothness. Would it help to reflect points out at the boundary so the local slopes continue and additional fictitious data is provided. Or is there another way, especially for the smoother methods, to make the behaviour at the boundaries more consistent with the otherwise C1/ C2 continuous nature of them?
naturalNeighbourInterp.mp4
Thanks!
For completeness, here is the code I used: