I have random uniform distributed points in a 3D plot. How can I subdivide the plot into cube shaped grids with equal volume.

My objective is to randomly and uniformly distribute points in a 3D cube shape. Then break the cube into 27 equal volume small cubes. then determine the density of points in each small cube (grid).
I have distributed points now but struggling to divide the plot into furether 27 sub cubes.
Help please

6 Comments

Is the cube arbitrarily oriented, or is it aligned with the x, y, z axes?
it is aligned with the axis such that 100x100x100 m3 volume can be divided into 27 equal volume cubes that cover the entire volume of 100x100x100 network
100x100x100 m3 volume can be divided into 27 equal volume cubes
That would require that each of the 27 sub-cubes was divided into sides of 33 1/3 m each. That 1/3 is going to present the majority of the complexity in your code; you are going to have to keep fighting it over and over.
Would it be acceptable to redefine from 100 meters per side, to 3936 inches per side? That is approximately 25.65 mm short of 100 meters, but at least then you could subdivide into 1312 inches per face (an integer) instead of having to deal with that pesky 1/3 .
I can modify 100 into 99 or any other value if this is easier. However, the code should be adaptive for dividing any cube into 27 small sub cubes is is possible?
the code should be adaptive for dividing any cube into 27 small sub cubes is is possible?
It gets messy. When the size of the larger cube is not divisible by 3, then there are 6 cut planes (2 per direction) along which it is necessary to figure out how to fairly count 1/3 or 2/3 of a pixel on each side of the cut plane. As you are calculating volumes, if you were to allocate the boundary pixel to both sides, then you would be over-estimating the volume.
A typical approach to try to be accurate and fair at the boundary involves looking at configurations of pixels at the boundary and saying that certain configurations of pixels count for one side or the other. For example if you have a conformation such as
*
*
**
*
and the boundary runs 1/3 of the way through the vertical line that has the single * then probably the fairest way would be to count it as being entirely on the right hand side, saying that the 1/3 of a pixel on the left of the boundary of what is clearly a surface, has "no significant presense" on the left side of the boundary and should only be counted on the right.
The major alternative is to count whole pixels that are entirely inside, and to count a fraction for one ones that are on the boundary.

Sign in to comment.

 Accepted Answer

N=1e3; % Number of points
cubesize = 100; % meter
subdivision = 3; % == 27^(1/3)
subcubesize = cubesize/subdivision;
% Generare N points in big cube V :) (0,cubsize)^3
xyz=cubesize*rand(N,3);
% Compute the density of 27 small cubes
ijk = ceil(xyz/subcubesize);
n = accumarray(ijk,1,subdivision*ones(1,3));
density = n/subdivision^3 % #points per m^3 in each of 27 subcubes
close all
scatter3(xyz(:,1),xyz(:,2),xyz(:,3));
hold on
h = slice([0 cubesize],[0 cubesize],[0 cubesize],zeros(2,2,2),...
(0:3)*subcubesize,(0:3)*subcubesize,(0:3)*subcubesize);
set(h,'FaceColor','none')
axis equal

11 Comments

Thank you this is how I want to subdivide the 100x100x100 volume into sub cubes with one third of Hundred.
However the issues with this one would be:
  1. the random distribution could fall on the division line because it is done in the 100x100x100 cube and if a node falls on the boundary line between the two cubes would that be accounted into density calculation of one cube or the other?
  2. how can I calculate the spherical distance of each point in one cube with all the other points in the same cube.
you have solved a lot of my problem already thank you I appreciate
The probability it's fall exactly into a separation is 0. But if it happens the point is considered belong only to one cube, not two.
For the second question, please open the new thread.
@Bruno Luong Thank you for your answe. I have started a new thread. Could you help me with the related issue
@Bruno Luong thank you for all the support upto now. Appologies for counter questions. I am new to MATLAB coding and probably not the coding mind (since I am old enough for this).
I just wanted to adjust this in my original deployment.
if I had the below code and I wish to break these already generated random points deployment on a cubical subdivided space as you have suggested above.
clear all
xm=100;
ym=100;
zm=100;
x=0;
y=0;
z=0;
collector.x=0.5*xm;
collector.y=0.5*ym;
collector.z=0.5*zm;
n=100
for i=1:1:n
P(i).xd=rand(1,1)*xm;
XR(i)=P(i).xd;
P(i).yd=rand(1,1)*ym;
YR(i)=P(i).yd;
P(i).zd=rand(1,1)*zm;
ZR(i)=P(i).zd;
P(n+1).xd=collector.x;
P(n+1).yd=collector.y;
P(n+1).zd=collector.z;
hold on;
figure(1)
plot3(x,y,z,xm,ym,zm,S(i).xd,S(i).yd,S(i).zd,'ob',S(n+1).xd,S(n+1).yd,S(n+1).zd,'*r');
hold on;
grid on;
How should I do that?
Again thanks for all the support up til now.
I'll do the modification with my code since it's already has the formatting that is ready for splitting
N=1e4; % Number of points
cubesize = 100; % meter
subdivision = 3; % == 27^(1/3)
subcubesize = cubesize/subdivision;
% Generare N points in big cube V :) (0,cubsize)^3
xyz=cubesize*rand(N,3);
% Compute the density of 27 small cubes
ijk = ceil(xyz/subcubesize);
n = accumarray(ijk,1,subdivision*ones(1,3));
density = n/subdivision^3 % #points per m^3 in each of 27 subcubes
% Create a unique array of indexes of subcubes
[i,j,k] = ndgrid(1:subdivision);
% each row of all_ijk is 3-column vector, its values mean subcube-index in x/y/z direction
all_ijk=[i(:) j(:) k(:)];
% Where the points belong to?
[~, LOC] = ismember(ijk, all_ijk, 'rows');
% Split them by subcube
splitxyz = accumarray(LOC, (1:N)', [subdivision^3,1], @(idx) {xyz(idx,:)});
% Graphic output
close all
hold on
for k=1:length(splitxyz) % loop on subcubes
xyzk = splitxyz{k}; % all points in a subcubes
scatter3(xyzk(:,1),xyzk(:,2),xyzk(:,3));
end
h = slice([0 cubesize],[0 cubesize],[0 cubesize],zeros(2,2,2),...
(0:3)*subcubesize,(0:3)*subcubesize,(0:3)*subcubesize);
set(h,'FaceColor','none')
axis equal
view(3)
I have no idea what you are talking about. I'll delete all my answers since I can't understand what you ask.
sorry dont delete I was just asking for have you accounted for this bit in my cde
P(n+1).xd=collector.x;
P(n+1).yd=collector.y;
P(n+1).zd=collector.z;
your answers have helped me throughout dont delete
@Bruni Luong
Thank you for all the support I really appreciate this has helped me a lot.
It's just a middle point of the bigcube isn't it?
It's belong to the center subcube #(2,2,2)
That what you ask?
exactly. I could not distinguish that one since it is supposed to be the gateways or collector or sink node. I wanted to highlight it but I think you have helped me alot already I really appreciate this question is 99% solved.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2020a

Community Treasure Hunt

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

Start Hunting!