Hey,
I'm relatively new at coding, and I'm using Mathematica to create a 3D image of ellipsoids in a box. I have an array of major semi-axis lengths for the ellipsoids that I want, call it "axis", e.g.
axis = {16,16,14,12,10,8,6};
Now I have a desired ellipsoid volume fraction, call it "vol".
vol = 0.02; (or 2% volume fraction of ellipsoids)
The relationship of ellipsoid major semi-axis/minor semi-axis is "N", e.g. major semi-axis = N*minor semi-axis. The total volume of the ellipsoids is given by
total = Total[4/3Piaxis*(axis/N)^2];
I back-calculate the box dimension "h" to obtain the desired volume fraction using
h = (total/vol)^(1/3) since total/h^3 = vol
Now I have all of the information that I need for my ellipsoids and my box. I use an algorithm to place these ellipsoids in the box at random as follows:
img = {FaceForm[], EdgeForm[], Cuboid[{0, 0, 0}, {h, h, h}]}; (make a transparent box without edges)
(Graylevel ellipsoids in 3D) For[k = 1, k <= Length[totalparticles], k++, guessCount = 1;
(create an ellipsoid) While[k == k, longleng = totalparticles[[k]]; (*this is a dummy variable so that \ the ellipsoids are guaranteed not to extend beyond the box*)
(create the center point of the ellipsoid using three offsets) xoff = RandomReal[{0 + longleng, h - longleng}]; (*randomly choose a value between 0 and the \ width of the image to use as an x offset for the ellipsoid centroid*)
yoff = RandomReal[{0 + longleng, h - longleng}]; (*randomly choose a value between 0 and the \ width of the image to use as a y offset for the ellipsoid centroid*)
zoff = RandomReal[{0 + longleng, h - longleng}]; (*randomly choose a value between 0 and the \ width of the image to use as a z offset for the ellipsoid centroid*)
obj = Ellipsoid[{xoff, yoff, zoff}, {axis[[k]], axis[[k]]/N, axis[[k]]/N}];
(*place the ellipsoid just created into a 3D graphic with all of \ the other exiting ellipsoids*) graph = Graphics3D[{GrayLevel[.2, .2], img, GrayLevel[.2, .2], obj}, Method -> "Shrinkwrap", Boxed -> False];
(*flatten out the pixel data from a multi- dimensional array into a single vector of graylevels*) data = Flatten[ImageData[graph]];
(*check to see if any graylevels fall below a designated \ threshhold; if they do, then two ellipsoids are touching and the new ellipsoid needs to be \ replaced*) check = Select[data, # < 0.6 &, 1]; If[Length[check] == 0, Break[]]; guessCount++;];
img = Prepend[img, obj];];
Now I check the pixel data and make sure the desired volume fraction is what I want:
graphic2 = Graphics3D[{GrayLevel[.2, .7], img}, Method -> "Shrinkwrap", Boxed -> False]; Totalpixels = Dimensions[ImageData[graphic2]][[1]]* Dimensions[ImageData[graphic2]][[2]]; epixels = N[Length[Select[Flatten[ImageData[graphic2]], # < 1. &]]/3]; earea = Round[N[epixels/Totalpixels], .001]
where "img" is my 3D image of all of the ellipsoids, "epixels" is the number of pixels assigned to ellipsoids, and "earea" is the volume fraction of the image's ellipsoids. When I run all of this, the pixel volume fraction is always much higher than the desired volume fraction, usually by a factor of between 4 and 10 depending on "N" and "vol", and I can't figure out why. Any help would be greatly appreciated!!