3

I'm trying to create a dataset of raw volumetric data consisting of geometrical shapes. The point is to use volume ray casting to project them in 2D but first I want to create the volume manually.

The geometry is consisting of one cylinder that is in the middle of the volume, along the Z axis and 2 smaller cylinders that are around the first one, deriving from rotations around the axes.

Here is my function so far:

function cyl= createCylinders(a, b, c, rad1, h1, rad2, h2)

% a : data width
% b : data height
% c : data depth
% rad1: radius of the big center cylinder
% rad2: radius of the smaller cylinders
% h1: height of the big center cylinder
% h2: height of the smaller cylinders

[Y X Z] =meshgrid(1:a,1:b,1:c);  %matlab saves in a different order so X must be Y
centerX = a/2;
centerY = b/2;
centerZ = c/2;

theta = 0; %around y
fi = pi/4; %around x

% First cylinder
cyl = zeros(a,b,c);

% create for infinite height
R = sqrt((X-centerX).^2 + (Y-centerY).^2);

startZ = ceil(c/2) - floor(h1/2);
endZ = startZ + h1 - 1;

% then trim it to height = h1
temp = zeros(a,b,h1);
temp( R(:,:,startZ:endZ)<rad1 ) = 255;
cyl(:,:,startZ:endZ) = temp;

% Second cylinder

cyl2 = zeros(a,b,c);

A = (X-centerX)*cos(theta) + (Y-centerY)*sin(theta)*sin(fi) + (Z-centerZ)*cos(fi)*sin(theta);
B = (Y-centerY)*cos(fi) - (Z-centerZ)*sin(fi);

% create again for infinite height
R2 = sqrt(A.^2+B.^2);
cyl2(R2<rad2) = 255;

%then use 2 planes to trim outside of the limits
N = [ cos(fi)*sin(theta) -sin(fi) cos(fi)*cos(theta) ];

P = (rad2).*N + [ centerX centerY centerZ];
T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);
cyl2(T<0) = 0;

P = (rad2+h2).*N + [ centerX centerY centerZ];
T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);
cyl2(T>0) = 0;

% Third cylinder
% ...

cyl = cyl + cyl2;

cyl = uint8(round(cyl));

% ...

The concept is that the first cylinder is created and then "cut" according to the z-axis value, to define its height. The other cylinder is created using the relation A2 + B 2 = R2 where A and B are rotated accordingly using the rotation matrices only around x and y axes, using Ry(θ)Rx(φ) as described here.

Until now everything seems to be working, because I have implemented code (tested that it works well) to display the projection and the cylinders seem to have correct rotation when they are not "trimmed" from infinite height.

I calculate N which is the vector [0 0 1] aka z-axis rotated in the same way as the cylinder. Then I find two points P of the same distances that I want the cylinder's edges to be and calculate the plane equations T according to that points and normal vector. Lastly, I trim according to that equality. Or at least that's what I think I'm doing, because after the trimming I usually don't get anything (every value is zero). Or, the best thing I could get when I was experimenting was cylinders trimmed, but the planes of the top and bottom where not oriented well.

I would appreciate any help or corrections at my code, because I've been looking at the geometry equations and I can't find where the mistake is.

Edit: This is a quick screenshot of the object I'm trying to create. NOTE that the cylinders are opaque in the volume data, all the inside is considered as homogeneous material.

set of cylinders

George Aprilis
  • 1,140
  • 1
  • 9
  • 23

1 Answers1

1

I think instead of:

T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);

you should try the following at both places:

T = (X-P(1)) + (Y-P(2)) + (Z-P(3));

Multiplying by N is to account for the direction of the axis of the 2nd cylinder which you have already done just above that step.

Sardar Usama
  • 19,536
  • 9
  • 36
  • 58
Spectre
  • 682
  • 10
  • 26
  • I tried your suggestion but it doesn't seem to work. It creates incomprehensible results. I'm not sure also about the correctness of a statement like `cyl2(T<0) = 0;` Maybe the equations are correct but the trimming is wrong? Thank you for your help anyway. – George Aprilis Mar 19 '13 at 11:06