Determine if a point is inside a cube

25 vues (au cours des 30 derniers jours)
Lulu
Lulu le 16 Nov 2011
Modifié(e) : Matt J le 13 Oct 2024
Hi! There are given 8 vertices of a cube and a random point. How can I define that the point lies inside the cube? I wanted to create 2 vectors from the random point. These vectors should be parallel to X and Y axis (Z is not needed here). Then, if vectors intersect with cube sides 4 times, then the point lies inside a cube. But this seems to be too complex approach for this problem. Does someone know a simpler way? A code snipped would be very helpful. Thanks.
  1 commentaire
Honglei Chen
Honglei Chen le 16 Nov 2011
Could you give a little more information regarding the issue? Is the cube really a right-angle equal-side-length cube? Is the orientation arbitrary or it has to be aligned with axes? Maybe an example can clarify these.

Connectez-vous pour commenter.

Réponse acceptée

Image Analyst
Image Analyst le 16 Nov 2011
The way I'd do it is to call convhulln(). Basically it gives you the vertices of your set of 3D vertices that are on the convex hull. The convex hull is what you'd get if you basically wrapped a balloon around your points.
So all you have to do is to pass in your cube coordinates concatenated with your "test" point and see if it returns the cube coordinates. If it doesn't then the point is outside. If it does, then the cube is the convex hull and that must mean your test point is inside the cube. It's one line of code to call convhulln() and another to do the check to see if what it returns matches your cube coordinates. You should be able to do it. If you can't then it's your turn to supply us with code that generates cube coordinates and test points (one inside and one outside) so that we can do those two lines for you.
  2 commentaires
Lulu
Lulu le 16 Nov 2011
Thanks. I wrote the following code according to your idea:
% Create a cube
xyz = [0 0 0; 1 1 1; 0 0 1; 0 1 0; 1 0 0; 1 0 1; 1 1 0; 0 1 1];
random_point = [1 2 1]; % lies outside the cube
xyz = [xyz; random_point];
K = convhulln(xyz);
len = length(xyz(:,1));
inside = any(any(K==len))
Please let me know if there is a better implementation of your idea.
Image Analyst
Image Analyst le 17 Nov 2011
Well K looks more complicated than the 2D case. I'd have to think about it. But you'd have to call convhulln twice (once for cube and once for cube + extra points) and use ismember to compare that each row of K1 is included in K2.

Connectez-vous pour commenter.

Plus de réponses (3)

sajjad nasiri
sajjad nasiri le 18 Juil 2018
Hi. Check this: https://uk.mathworks.com/matlabcentral/fileexchange/68228-incube

Mustafa Cavdir
Mustafa Cavdir le 13 Oct 2024
Modifié(e) : Mustafa Cavdir le 13 Oct 2024
Hello, I had the same problem. Programming 3D-heatflow to calculate thermal contact heat coefficient. The intersecting edges of the cubes are normal to each other and the 6 faces are parallel to the cartesian coordinates. If we have more cubes, they are not overlapping. A point can only in none or one cube (no overlapping cubes).
What I have done is to store the x-,y-z-coordinates of the volume-center and the dx-,dy- and dz-length of the cube(s). Computing the 6 cube faces with the formula:
xn = x - 1/2 * dx; % xn = x_negative
xp = x + 1/2 * dx; % xp = x_positive
yn = y - 1/2 * dy;
yp = y + 1/2 * dy;
zn = z - 1/2 * dz;
zp = z + 1/2 * dz;
For less storages, we can only store this 6 faces if we don't need the other values x,y,z,dx,dy and dz.
Now, the point is inside a cube which has the coordinates px, py and pz, if following statements are true:
point_in_cube = (px > xn) & (px < xp) & (py > yn) & (py < yp) & (pz > zn) & (pz < zp);
If the point is on the face or extremely near to the face, we can have round-errors. To remove this we can create a function, which calculates the relative percentage distance. Something like isequal_tol...
Efficiency:
With this basic we can compute several cubes and several points in one time. Obtaining a large set of points and many cubes, an "active set method" is a great deal. That means we compute the above statement first in one direction, delete those points which aren't in any cube, and do the same to the other directions. Starting with a specific direction can be faster in dependence of the distribution of the points/cubes.
nof = 100; % nof = number_of_points
pidx = 1:nof; % point_idx
pidx = pidx((px(pidx) > xn) & (px(pidx) < xp)); % pic = point_in_cube (here not logical-array)
pidx = pidx((py(pidx) > yn) & (py(pidx) < yp));
pidx = pidx((pz(pidx) > zn) & (pz(pidx) < zp));
disp('points in cube:')
disp(pidx)
In my case, I used the active-set-method to the cubes and not to the points (because every point must be in only one cube and there can be cubes in which aren't points - all points are active) and stored which point is in which cube - like an array [p_idx, cube_idx]. I did it, but my developed code is not efficient using large matrices. To do this efficiently, I think creating a 3D or 4D matrix or vectorizing it somehow and avoiding a for-loop could be better. Using a for-loop we can loop over the cubes or points. Knowing there are more cubes than points, looping over cubes should be faster or vice versa. Having a proper idea of the distribution of the points/cubes can help us.
Thinking now, how to do this in best matter...
The above statements can have improper commands. I just showed it up shematically. Hope this helps. Greetings

Matt J
Matt J le 13 Oct 2024
Modifié(e) : Matt J le 13 Oct 2024
Assuming the cube is not rotated,
vertices = [
-1, -1, -1;
-1, -1, 1;
-1, 1, -1;
-1, 1, 1;
1, -1, -1;
1, -1, 1;
1, 1, -1;
1, 1, 1
];
point1=[0,0,0];
point2=[3,0,2];
vmax=max(vertices);
vmin=min(vertices);
inside1 = all(point1>=vmin & point1<=vmax)
inside1 = logical
1
inside2 = all(point2>=vmin & point2<=vmax)
inside2 = logical
0

Catégories

En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by