I want to estimate the shape of convex 3d object. First let me give an example on 2d:
Lets say there is convex shape given by black color in the figure. We don't know its shape, but we are given points A,B,C,D. Using convexhull and trisurf commands on Matlab, we can plot "interior" convex hull given by blue color. Now, if we are given not only points A,B,C,D but also tangent lines to the black colored object through these points, we can plot "outer" convex hull through the points A1,B1,C1,D1. The "outer" convex hull is more difficult to plot, because there are many points where tangent lines intersect, so we need to find some way to obtain specifically A1,B1,C1,D1.
In 3d, we are given the points and tangent planes to these points in terms of plane equations ax+by+cz=d. Here is Matlab program that generates next two figures:
load("planedata.mat");
load("planedata_d.mat");
load("points.mat");
a=planedata(1:100,1);
b=planedata(1:100,2);
c=planedata(1:100,3);
d=planedata_d;
figure(1)
x = points(1,:); y = points(2,:); z = points(3,:);
[k1,av1] = convhull(x,y,z);
trisurf(k1,x,y,z); %plot interior convex hull
xlabel('$X$','Interpreter','latex');
ylabel('$Y$','Interpreter','latex');
zlabel('$Z$','Interpreter','latex');
figure(2)
[X,Y] = meshgrid(x,y);
for i=1:100
Z=real(-(a(i)*X+b(i)*Y+d(i))/c(i));
hold on
surf(X,Y,Z); %plot exterior convex hull
end
xlim([-1 2])
ylim([-1 2])
zlim([0 4])
xlabel('$X$','Interpreter','latex');
ylabel('$Y$','Interpreter','latex');
zlabel('$Z$','Interpreter','latex');
You can download the data file from here. First, we just plot "interior" convex hull for given points:
Then the tangent planes:
And also I can see the shape of the "exterior" convex hull only by cutting all planes at specific height like this:
Is there any way to remove all the planes and plot only the "exterior" convex hull, so the figure looks like "interior" convex hull, but of course a little larger in size?
Related
I wish to put 2D curve fitting to different axis within a 3D plot. I am attaching an image for reference.
on this actual data set:
As you can see the curve fitting for x and y axis is at z=0 value, I need that at say z=10.
Further, when I try to do curve fitting for x and z data set or y and z data set, the fitted curve instead of appearing on the the X-Z plane or Y-Z plane, is appearing on the X-Y plane.
All help is appreciated.
First I have ploted a convex hull for given points using convexHull Matlab function:
x = [4*rand(10,1)-2];
y = [rand(10,1)+5];
DT = delaunayTriangulation(x,y);
C = convexHull(DT);
plot(DT.Points(:,1),DT.Points(:,2),'.','MarkerSize',10)
hold on
plot(DT.Points(C,1),DT.Points(C,2),'r')
This convex hull is just an example, it can be any other convex hull. We assume that convex hull is inside parabola y=x^2.
Then I want to find first point on convex hull that touches line y=[(a^2+1)/a]x-1, when we start from a=1 and it can go until a=+\infty if never touches convex hull (when convex hull is on LHS).
How that can be accomplished? My final goal is to find a on the figure.
For each corner (x_i, y_i) of the polygon solve quadratic equation for a_i.
y_i*a_i = (a_i^2 + 1)*x_i - 1
You can obtain the equation by putting the point coordinates into the line equation. Next, discard solutions that are not relevant for You (a<1). Once this is done, sort solutions by a. If you also need the index of corresponding vertex, sort function in Matlab gives you indexing array as an additional output. You can then plot the line.
As a corner case, the line may hit two vertices. This is not a problem if you just need a. If you want the vertex id, just discard one arbitrarily, or use some additional rule.
I created 3D convex hull plot in Matlab. It seems in this function, some of laser points were used for facets of convex hull, but some other points are situated inside convex hull . My question is that how can I identify these points in Matlab separately. Which way is applicable for calculating the perpendicular distance of these points situated inside of convex hull to the nearest convex hull facet (distance from each point to the closest facet of the convex hull)?
I would be very grateful if you could introduce me some references about convex hull function.
On the Matlab file exchange, there is a great function called inhull, which will test whether your points are inside the hull or not. I'm not sure that it provides the distance from the points to the nearest facet, but perhaps the methods used in the code would be simple to change to provide this output.
Check out the function, tsearchn.
The following code creates a sphere in 3D and computes the delaunay triangularization. We then set-up testpoints variable with points to test if they are inside the sphere or not. t returns indices back into TRI for tetrahedra facet that are closest to the point or NaN if the point is outside the sphere.
[X,Y,Z] = sphere(N);
TRI = delaunay(X(:),Y(:),Z(:));
testpoints = [0 0 0; 0 .5 0; 1 2 0]
t = tsearchn([X(:) Y(:) Z(:)],TRI,testpoints)
figure;
trisurf(TRI,X(:),Y(:),Z(:));
Output is,
t =
8182
7779
NaN
I have generated a rectangular matrix with the azimouth angle changing with rows and the radius changing as you change column. These are meant to represent the relative velocities experienced by a rotating helicopter blade. This produces a matrix called Vmat. I want to plot this to appears in a circle (representing the rotation of the blade)
So far I have tried
[R,T] = meshgrid(r,az);
[x,y] = pol2cart(T,R);
surf(x,y,Vmat(r,az));
which should produce a contoured surface showing velocity as it changes with azimouth angle and radius but it comes up with dimension errors.
I don't mind if it is a 2d contour plot or 3d plot i guess both would be written in a similar way.
Thanks
James
The error is in writing Vmat(r,az), presuming that these are actual values of radius and azimuth, not indexes into your radius and azimuth. If you want to take only a subset of Vmat that's a slightly different matter, but this should work:
[R,T] = meshgrid(r,az); % creates a grid in polar coordinates
[x,y] = pol2cart(T,R); % changes those to cartesian for surf
surf(x,y,Vmat);
Alternatively you could do a contour plot:
h = polar([0 2*pi], [0 max(r)]); % set up polar axes with right scale
delete(h) % remove line
hold on
contour(x,y,Vmat);
I have a large (~60,000) set of triplet data points representing x,y, and z coordinates, which are scattered throughout a Cartesian volume.
I'm looking for a way to use Matlab to visualize the non-convex shape/volume described by the maximum extent of the points.
I can of course visualize the individual points using scatter3, but given the large number of points the details of the shape are obscured by the noise of the dots.
As an analogy, imagine that you filled a hour glass with spheres of random sizes such as BBs, ping pong balls, and kix and then were given the coordinates of the center of each of each object. How would you take those coordinates and visualize the shape of the hour glass containing them?
My example uses different sized objects because the spacing between data points is non-uniform and effectively random; it uses an hourglass because the shape is non-convex.
If your surface enclosing the points can be described as a convex polyhedron (i.e. like the surface of a cube or a dodecahedron, without concave pits or jagged pointy parts), then I would start by creating a 3-D Delaunay triangulation of the points. This will fill the volume around the points with a series of tetrahedral elements with the points as their vertices, and you can then find the set of triangular faces that form the outer shell of the volume using the convexHull method of the DelaunayTri class.
Here's an example that generates 200 random points uniformly distributed within the unit cube, creates a tetrahedral mesh for these points, then finds the 3-D convex hull for the volume:
interiorPoints = rand(200,3); %# Generate 200 3-D points
DT = DelaunayTri(interiorPoints); %# Create the tetrahedral mesh
hullFacets = convexHull(DT); %# Find the facets of the convex hull
%# Plot the scattered points:
subplot(2,2,1);
scatter3(interiorPoints(:,1),interiorPoints(:,2),interiorPoints(:,3),'.');
axis equal;
title('Interior points');
%# Plot the tetrahedral mesh:
subplot(2,2,2);
tetramesh(DT);
axis equal;
title('Tetrahedral mesh');
%# Plot the 3-D convex hull:
subplot(2,2,3);
trisurf(hullFacets,DT.X(:,1),DT.X(:,2),DT.X(:,3),'FaceColor','c')
axis equal;
title('Convex hull');
You could treat your data as a sample from a three-dimensional probability density, and estimate that density on a grid, e.g. via a 3d histogram, or better a 3d kernel density estimator. Then apply a threshold and extract the surface using isosurface.
Unfortunately, hist3 included in the Statistics Toolbox is (despite its name) just a 2d histogram, and ksdensity works only with 1d data, so you would have to implement 3d versions yourself.