I have a point cloud of a tree trunk, imported as a ply file. It is a point cloud so the tree trunk is not a surface, but points with gaps in between. I also have the 3D coordinates of a bunch of points. How do I remove those points that are not inside the tree trunk? The model is not parallel with the axes by the way. Here's a dropbox link for the ply file. Coordinates and values of the points are in the attached all_control_points.mat file. There's no code yet except the ones to generate this data.
Neeta Dsouza answered .
2025-11-20

% xc,yc,zc - control points (red on the image)
% xt,yt,zt - tree point (blue on the image)
ri = sqrt(xt(it).^2 + yt(it).^2); % radius of tree points
ri1 = griddata(xt(it), yt(it), zt(it), ri, ...
xc,yc,zc);
griddata() generates radius for points inside only (NaN for other)
% clc,clear
% load data.txt
Xt = X12(:,1);
Yt = X12(:,2);
Zt = X12(:,3);
% rotate data by 75 degree about X axis
a = -75;
xt = Xt;
yt = Yt*cosd(a) + Zt*sind(a);
zt = -Yt*sind(a) + Zt*cosd(a);
% center data (move to (0,0))
x0 = mean(xt);
y0 = mean(yt);
xt = xt - x0;
yt = yt - y0;
it = 1:100:length(Xt); % reduce data for faster calculation
plot3(xt(it),yt(it),zt(it),'.b')% draw points
% load all_control_points.mat
Xc = control_points(:,1);
Yc = control_points(:,2);
Zc = control_points(:,3);
% do the same with control point (rotate and move)
xc = Xc;
yc = Yc*cosd(a) + Zc*sind(a);
zc = -Yc*sind(a) + Zc*cosd(a);
xc = xc - x0;
yc = yc - y0;
% small trick:
% generate new radius for control points
% i imagine it like a kind of projection on the tree
ri = sqrt(xt(it).^2 + yt(it).^2); % radius of tree points
ri1 = griddata(xt(it), yt(it), zt(it), ri, ...
xc,yc,zc);
ic = ~isnan(ri1); % inside the tree
hold on
plot3(xc(ic),yc(ic),zc(ic),'og')
plot3(xc,yc,zc,'.r')
hold off
xlabel('X axis')
ylabel('Y axis')