Finding point inside pointcloud - matlab

I have a pointcloud made by X Y Z matrices. They make a volume. I want to check if a point (x, y, z) is inside this cloud, e. g. in the volume that is inside the pointcloud. How can I do this in Matlab?
I have tried to simply extrapolate Xmax, Xmin, Ymax,Ymin and Zmin and Zmax, and finding points that are between these values. However, the shape is irregular, so this gives points which are not inside the cloud.
Does the pointCloud function in MatLab give the option to check if a set of points is inside a given cloud?
Thanks!

Related

Can Matlab do a 3D plot with a 4th variable as color map?

I'm exploring contour3 and mesh, but don't see any path to take 3 variable data (x, y, z) and another variable (e.g. a = fn(x, y, z)) that can be used to create a heat map or colored contour plot in that 3D space.
Please point me in the right direction.

How to extract xyz coordinates from 3D point cloud in MATLAB

I am using a Kinect for Windows to import 3D images into MATLAB. I want to be able to find the 3D co-ordinates of objects within the 3D scene.
One simple way to do this is to use the clickA3DPoint function found here, and then click the point I want to know the co-ordinates of.
The problem is clickA3DPoint expects the arguments in a 3 by N matrix, which is the x y and z coordinates of N samples. When I use the Kinect to get a point cloud with depthToPointCloud it returns a 480 * 640 * 3 matrix.
How can I extract the x, y, and z coordinates from this matrix so I can plot it with clickA3DPoint? (or scatter3?)
My attempt so far:
depthDevice = imaq.VideoDevice('kinect',2) %this is the kinect depth sensor
depthImage = step(depthDevice); %this takes a depth image. (A 480 * 640 uint16 array)
xyzPoints = depthToPointCloud(depthImage,depthDevice); %convert the depth image to a point cloud
clickA3DPoint(reshape(xyzPoints,[3,307200])) %I'm guessing each of the 480 * 640 points (307200 points) has an x,y and z coordinate, so this concates the coordinates of all these points.
But this just plots the points along a diagonal line in the 3D space. How do I actually extract the x, y and z coordinates from a point cloud in Matlab?
You can use the pcshow function to plot your points, and it will take the M-by-N-by-3 array directly. You can then turn on data tips and click on the points in the plot to see their coordinates.
If you still want to create a 3-by-N matrix, then the easiest way to do that is the following:
x = xyzPoints(:,:,1);
y = xyzPoints(:,:,2);
z = zyzPoints(:,:,3);
points3D = [x(:)'; y(:)', z(:)'];
you can use the Property 'Location' of pointCloud to get the x,y,z.
for example:
moving = movingReg.Location;%movingReg is a pointCloud
scatter(moving(:,1),moving(:,2));

Matlab's curl function and its limitation?

Iam beginner to matlab. Still learning it.Recently i have been asked to compute curl of three velocity components and plot its contour w.r.t circumferential angle along x-axis and radius along y-axis. The data u,v and w is pre-calculated by me as follows
u = V * Cos(beta) * cos(alpha); % V is velocity in m/s and alpha,beta are angles in radians
similarly
v = V * cos(beta) * sin(alpha);
w = V * sin(alpha)
Someone recently commented out saying that to enable mat lab's curl functionality my u,v and w data should be in Cartesian coordinate. I relied saying that though my initial data is in spherical coordinates(V,alpha,beta) but iam using coordinate conversion on u,v and w and transforming my data to Cartesian coordinate.
He further replied saying that "not only u,v,w should be Cartesian but its relative data x,y,z should also need to be Cartesian coordinate"
I dint get it. Can anyone say what he was trying to say or if i can use the curl functionality in matlab
I shall be gretful for your help and answer
I have not tried the function, but as far as it concerns the coordinates u, v, w defines the force for each gridspace from x, y, z. However, the help on mathworks homepage says that x, y, z
must be monotonic, but do not need to be uniformly spaced.
This may be a trouble for spherical coordinates, when transformed to cartesians. I assume that weakly monotonic for any coordinate (but not all of them) would work, but spherical coordinates does not apply for that. What you could try is to transform the coordinates but make sure that the grid is monotonic. I mean, you make sure the grid in Cartesian coordinates is kept monotonic instead of the spherical.
So the answer is then more explicitly x, y, z, need to be non decreasing with at least 1 coordinate at the time which is increasing, but the force of each point can have the value of spherical coordinate transformed to its corresponding Cartesian value.
Except for this I would like to advise you to use the formal definition of spherical coordinates, which defines alpha as the angle from z to the xy-plane (alpha = 0 is the z-axis). I would also recommend you to use the more common coordinate names. r, phi and theta.

Matlab - Multiple 2D plots along a 3rd dimension

I'm trying to plot many 2D plots (x,y).
But...
each 2D plot is for a constant z.
So really my data is (x,y,z) but not z(x,y), which I believe are the requirements for using the "surf" command.
Could anyone help with this?
Example,
x = velocity
y = drag
I have multiple runs of y(x) for a constant temperature, z.
I just want to plot each (x,y) along a 3rd axis, temperature z.
Ideally I'd also want some sort of contour between the (x,y) plots so I can show the peaks/troughs etc.
Any help would be great.
If the runs are not independent (there is some trend over multiple runs) then it may make sense to use surf. You then need to construct your data such you have an X,Y, and Z - in this case I'd suggest you use the drag measurements as your Z (height).
Assuming that you have all the drag/velocity data in drag and velocity which are both of size [data points x number of runs]:
% construct matrix of run numbers
runs = repmat(1:numruns, [1, datapoints]);
runs = reshape(runs, datapoints, numruns);
% plot and label
surf(runs,velocity,drag);
xlabel('runs')
ylabel('velocity')
zlabel('drag')

Matlab -plot a vector field

I have written a function in Matlab that gives me a vector at a position (x,y,z).
Now I am looking for the easiest way to make a colored map of this field on a grid and the color should be related to the norm of the vector.
What is the easiest way to define such a grid for $x \in [x_0,x_1],y \in [y_0,y_1], z \in [z_0,z_1]$? Probably linspace for each component would be possible, but maybe there is already a command that gives me the grid.
Now I need to evaluate my function. The problem is, that it actually gives me two vectors, but I am only interested in the first one. So when I first tried to do this I thought that $[A(i,j,k),~]=function(x(i),y(j),z(k))$ could work, but it did not(My goal was: Choose the first vector(A) and mark him with the reference(i,j,k), so that you later on know to which coordinates this vector belongs to).
So I am highly interested in any kind of ideas.
The function meshgrid might be what you are looking for to generate the x, y and z coordinates.
Instead of
[A(i,j,k),~]=function(x(i),y(j),z(k));
try
[A(i,j,k,:),~]=function(x(i),y(j),z(k));
so that you can fit the entire size of the 3-coordinate vector. Also, if you want to preallocate space use
A = zeros(Nx,Ny,Nz,3);
where Nx,... are the dims of your coordinate space. Then like #Moly explains, use meshgrid to generate a 3D grid,
[X Y Z] = meshgrid(x,y,z);
and loop or vectorize to resolve values of your function at points X(i,j,k),Y(i,j,k),Z(i,j,k), compute the norm and store it in 3D array C.
Edit
Representing a cube with mesh(X,Y,Z,C) is not possible but individual slices of the 3D cube can be visualized with mesh, setting the height Z equal to the result of the function C. Some additional work is then required to get coloring right.
Yet another alternative is to use pcolor or contourf. This is perhaps the easiest way to show the 4D data beyond creating a 3D isosurface.
code:
figure
colormap(jet)
for ii=1:9
subplot(3,3,ii)
pcolor(X(:,:,ii),Y(:,:,ii),F(:,:,ii))
axis('equal','square'), title(['Z=' num2str(ii)])
caxis([0 1])
end