Crop 3D Mesh with plane Cut in Matlab - matlab

I have made 3D analysis code and I want to split or crop 3D mesh into 2 parts with 2D plane, what i expected: the final result I need is to find out what are the nodes on the left side and the right side, what you see on the image below is the nodes of the 3D object (bumpy), Do you know what method or library I need to use to solve this problem?
my problem
Here is my data structure from the 2D plane:
Column 1: Face
Column 2: X coordinate
Column 3: Y coordinate
column 4: Z coordinate
Column 5: Finite Element Value
data structure
.
The data structure from the 3D mesh is containing the same data as the table above, Thanks so much!
We can know the plane XYZ Coordinates, so I tried to find by using <= to find the axis value is larger or smaller than the plane coordinates:
find x,y,z 3D model coordinate is smaller than x,y,z cut plane coordinate
[r] = find((Name_OT(:,1)>=x) & (Name_OT(:,2)>=y) & Name_OT(:,3)>=z);
the blue line is the plane, and the coloured one is the result from my code, the ideal result is the coloured nodes full, but what happened here the colour node has a big hole or gap
not good result

You need to first decide whether you want to segment your data by a (linear) plane or not. If you prefer to keep a curved surface, please follow my earlier comment and edit your question.
To get a plane fit to the data for your cut, you can use fit.
Base on the plane, you can get a normal vector of the plane. That is reading coefficients of fit results and is in the documentation. Using that normal vector, you can rotate all your data so that the plane is normal to z axis. The rotation is matrix multiplication. From there, you can use logical indexing to segment your data set.
You can ofc also get the normal component of the data points relative to the plane cut and decide on a direction that way. You still need fit. From that point, it's basic matrix manipulation. An nx1 vector can multiply a 1xn vector in Matlab. So projectors can also be constructed from basic matrix manipulation. At a glance, this method is computationally inefficient.

Related

I need to fit a best circle to the 3D data in matlab

Basically, I have a many irregular circle on the ground in the form of x,y,z coordinates (of 200*3 matrix). but I want to fix a best circle in to the data of x,y,z coordinates (of 200*3 matrix).
Any help will be greatly appreciated.
I would try using the RANSAC algorithm which finds the parameters of your model (in your case a circle) given noisy data. The algorithm is quite easy to understand and robust against outliers.
The wikipedia article has a Matlab example for fitting a line but it shouldn't be too hard to adapt it to fit a circle.
These slides give a good introduction to the RANSAC algorithm (starting from page 42). They even show examples for fitting a circle.
Though this answer is late, I hope this helps others
To fit a circle to 3d points
Find the centroid of the 3d points (nx3 matrix)
Subtract the centroid from the 3D points.
Using RANSAC, fit a plane to the 3D points. You can refer here for the function to fit plane using RANSAC
Apply SVD to the 3d points (nx3 matrix) and get the v matrix
Generate the axes along the RANSAC plane using the axes from SVD. For example, if the plane norm is along the z-direction, then cross product between the 1st column of v matrix and the plane norm will generate the vector along the y-direction, then the cross product between the generated y-vector and plane norm will generate a vector along the x-direction. Using the generated vectors, form a Rotation matrix [x_vector y_vector z_vector]
Multiply the Rotation matrix with the centroid subtracted 3d points so that the points will be parallel to the XY plane.
Project the points to XY plane by simply removing the Z-axes from the 3d points
fit a circle using Least squares circle fit
Rotate the center of the circle using the inverse of the rotation matrix obtained from step 5
Translate back the center to the original location using the centroid
The circle in 3D will have the center, the radius will be the same as the 2D circle we obtained from step 8, the circle plane will be the RANSAC plane we obtained from step 3

Smooth circular data - Matlab

I am currently doing some image segmentation on a bone qCT picture, see for instance images below.
I am trying to find the different borders in the picture for instance the outer border separating the bone to the noisy background. In this analysis I am getting a list of points (vec(1,:) containing x values and vex(2,:) containing the y values) in random order.
To get them into order I am using using a block of code which effectively takes the first point vec(1,1),vec(1,2) and then finds the closest point among the rest of the points in the vector. And then repeats.
Now my problem is that I want to smooth the data but how do I do that as the points lie in a circular formation? (I do have the Curve Fitting Toolbox)
Not exactly a smoothing procedure, but a way to simplify your data would be to compute the boundary of the convex hull of the data.
K = convhull(O(1,:), O(2,:));
plot(O(1,K), O(2,K));
You could also consider using alpha shapes if you want more control.

Minimizing area of a triangle containing data points in 3D plane

I have a set of data in 3D which are in the same plane. I have a Triangle containing those data points in the same plane. But the Area of the Triangle is much larger. I want to find the smallest area triangle (co-ordinate of its 3 points) containing all the data point inside it. There are some concepts available for 2D data points, but I need to find this in 3D dimension.
It looks like Matlab has a function for this, convhull. You want to find the convex hull of the data set. http://www.mathworks.com/help/matlab/ref/convhull.html This function works for points in 2d or 3d space.

pca in matlab - 2D curve stretching

I have N 3D observations taken from an optical motion capture system in XYZ form.
The motion that was captured was just a simple circle arc, derived from a rigid body with fixed axis of rotation.
I used the princomp function in matlab to get all marker points on the same plane i.e. the plane on which the motion has been done.
(See a pic representing 3D data on the plane that was found, below)
What i want to do after the previous step is to look the fitted data on the plane that was found and get the curve of the captured motion in 2D.
In the princomp how to, it is said that
The first two coordinates of the principal component scores give the
projection of each point onto the plane, in the coordinate system of
the plane.
(from "Fitting an Orthogonal Regression Using Principal Components Analysis" article on mathworks help site)
So i thought that if i just plot those pc scores -plot(score(:,1),score(:,2))- i'll get the motion curve. Instead what i got is this.
(See a pic representing curve data in 2D derived from pc scores, below)
The 2d curve seems stretched and nonlinear (different y values for same x values) when it shouldn't be. The curve that i am looking for, should be interpolated by just using simple polynomial (polyfit) or circle fit in matlab.
Is this happening because the plane that was found looks like rhombus relative to the original coordinate system and the pc axes are rotated with respect to the basis of plane in such way that produce this stretch?
Then i thought that, this is happening because of the different coordinate systems of optical system and Matlab. Optical system's (ie cameras) co.sys. is XZY oriented and Matlab's default (i think) co.sys is XYZ oriented. I transformed my data to correspond to Matlab's co.sys through a rotation matrix, run again princomp but i got the same stretch in the 2D curve (the new curve just had different orientation now).
Somewhere else i read that
Principal Components Analysis chooses the first PCA axis as that line
that goes through the centroid, but also minimizes the square of the
distance of each point to that line. Thus, in some sense, the line is
as close to all of the data as possible. Equivalently, the line goes
through the maximum variation in the data. The second PCA axis also
must go through the centroid, and also goes through the maximum
variation in the data, but with a certain constraint: It must be
completely uncorrelated (i.e. at right angles, or "orthogonal") to PCA
axis 1.
I know that i am missing something but i have a problem understanding why i get a stretched curve. What i have to do so i can get the curve right?
Thanks in advance.
EDIT: Here is a sample data file (3 columns XYZ coords for 2 markers)
w w w.sendspace.com/file/2hiezc

Extract arbitrarily rotated plane of data from 3D array as 2D array

I have a 3D matrix of data in matlab, but I want to extract an arbitrarily rotated slice of data from that matrix and store it as a 2D matrix, which I can access. Similar to how the slice() function displays data sliced at any angle, except I would also like to be able to view and modify the data as if it were an array.
I have the coordinates of the pivot-point of the plane as well as the angles of rotation (in x, y and z axis), I have also calculated the equation of the plane in the form:
Ax + By + Cz = D
and can extract a 3D matrix containing only the data that fall on that plane, but I don't know how to then convert that into a simple 2D array.
Another way of doing it would be to somehow rotate the source matrix in the opposite direction of the angle of the plane, so as to line up the plane of data with the XY axis, and simply extract that portion of the matrix, but I do not know if rotating a matrix like that is possible.
I hope this hasn't been answered elsewhere, I've been googling it all day, but none of the problems seem to exactly match mine.
Thanks
You can take a look at the code here. I think the function is similar to what you are trying to solve.
The function extracts an arbitrary plane from a volume given the size of the plane, the center point of the plane, and the plane normal, i.e. [A,B,C]. It also outputs the volumetric index and coordinate of each pixel on the plane.
Aha! May have just solved it myself.
To produce the plane equation I rotate a normal vector of (0,0,1) using rotation matrices and then find D. If I also rotate the following vectors:
(1,0,0) //step in the x direction of our 2D array
and
(0,1,0) //step in the y direction of our 2D array
I'll have the gradients that denote how much my coordinates in x,y,z have to change before I step to the next column in my array, or to the next row.
I'll mock this up ASAP and mark it as the answer if it works
EDIT: Ok slight alteration, when I'm rotating my vectors I should also rotate the point in 3D space that represents the xyz coordinates of x=0,y=0,z=0 (although I'm rotating around the centre of the structure, so it's actually -sizex/2,-sizey/2,-sizez/2, where size is the size of the data, and then I simply add size/2 to each coordinate after the rotations to translate it back to where it should be).
Now that I have the gradient change in 3D as I increase the x coordinate of my 2D array and the gradient change as I increase the y coordinate, I can simply loop through all possible x and y coordinates (the resulting array will be 50x50 for a 50x50x50 array, I'm not sure what it will be for irregular sizes, which I'll need to work out eventually) in my 2D array and calculate the resulting 3D coordinates on my plane in the data. My rotated corner value serves as the starting point. Hooray!
Just got to work out a good test for this encompassing all angles and then I'll approve this as an answer