|
a |
|
b/Cobiveco/functions/baryInterpMat.m |
|
|
1 |
function M = baryInterpMat(P, C, targetPoints) |
|
|
2 |
% Computes a matrix to interpolate values from the nodes of a source |
|
|
3 |
% tetrahedral mesh to a set of target points (barycentric interpolation). |
|
|
4 |
% |
|
|
5 |
% M = baryInterpMat(P, C, targetPoints) |
|
|
6 |
% |
|
|
7 |
% Inputs: |
|
|
8 |
% P: points of the source mesh [numSourcePoints x 3] |
|
|
9 |
% C: cells of the source mesh [numSourceCells x 4] |
|
|
10 |
% targetPoints: target points [numTargetPoints x 3] |
|
|
11 |
% |
|
|
12 |
% Outputs: |
|
|
13 |
% M: interpolation matrix [numTargetPoints x numSourcePoints] |
|
|
14 |
% |
|
|
15 |
% Written by Steffen Schuler, Institute of Biomedical Engineering, KIT |
|
|
16 |
|
|
|
17 |
if ~isa(P,'double'), P = double(P); end |
|
|
18 |
if ~isa(C,'double'), C = double(C); end |
|
|
19 |
if ~isa(targetPoints,'double'), targetPoints = double(targetPoints); end |
|
|
20 |
|
|
|
21 |
TR = triangulation(C,P); |
|
|
22 |
baryCellIds = pointLocation(TR, targetPoints); |
|
|
23 |
|
|
|
24 |
% For points that are not inside any tetrahedron (this may also be points |
|
|
25 |
% on the boundary of the mesh), find the tetrahedron with the closest |
|
|
26 |
% centroid and use its barycentric coordinates for extrapolation |
|
|
27 |
notFound = isnan(baryCellIds); |
|
|
28 |
if any(notFound) |
|
|
29 |
centroids = squeeze(mean(reshape(P(C,:),[],size(C,2),size(P,2)),2)); |
|
|
30 |
tmp = vtkMapIds(vtkCreateStruct(centroids), vtkCreateStruct(targetPoints(notFound,:))); |
|
|
31 |
baryCellIds(notFound) = tmp.pointData.MappedIds; |
|
|
32 |
end |
|
|
33 |
|
|
|
34 |
baryPointIds = C(baryCellIds,:); |
|
|
35 |
baryCoords = cartesianToBarycentric(TR, baryCellIds, targetPoints); |
|
|
36 |
|
|
|
37 |
m = size(baryCoords,1); |
|
|
38 |
n = size(P,1); |
|
|
39 |
i = reshape(repmat((1:m)',1,4),[],1); |
|
|
40 |
j = baryPointIds(:); |
|
|
41 |
v = baryCoords(:); |
|
|
42 |
M = sparse(i,j,v,m,n); |
|
|
43 |
|
|
|
44 |
end |