Question

After constructing the point cloud I want to get the normal of each point and I used the built-in matlab function surfnorm but its takes a lot of processing time. So if anyone could assist me do this a better and more efficient way.

Was it helpful?

Solution

I wonder if the following code would help you. There are three steps here.

  1. Create 500 randomly spaced points (x,y), and compute a corresponding value z (the height of the surface) for which I chose a sinc like function
  2. Resample the random points using the TriScatteredInterp function - this permits me to obtain points on an evenly sampled grid that "roughly correspond" to the initial surface
  3. Compute the normal to "some points" on that grid (since there are 480x640 points, computing the normal at every point would just create an impossibly dense "forest of vectors"; by sampling "every 10th point" you can actually see what you are doing

The code I used was as follows:

randomX = rand(1,500);
randomY = rand(1,500);
r = 5*sqrt(randomX.^2 + randomY.^2);
randomZ = sin(r) ./ r;

% resample the data:
[xx yy] = meshgrid(linspace(0,1,640), linspace(0,1,480));
F = TriScatteredInterp(randomX(:), randomY(:), randomZ(:));
zz = F(xx, yy);

%% at each point, the normal is cross product of vectors to neighbors
xyz=reshape([xx yy zz],[size(xx) 3]);
xv = 10:30:479; yv = 10:30:639; % points at which to compute normals
dx = xyz(xv, yv+1, :) - xyz(xv, yv, :);
dy = xyz(xv+1, yv, :) - xyz(xv, yv, :);

normVecs = cross(dx, dy); % here we compute the normals.
normVecs = normVecs ./ repmat(sqrt(sum(normVecs.^2, 3)), [1 1 3]);

figure;
quiver3(xx(xv, yv), yy(xv, yv), zz(xv, yv), ...
    normVecs(:,:,1), normVecs(:,:,2), normVecs(:,:,3));
axis equal
view([56 22]);

And the resulting plot:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top