создавать цилиндры в трехмерных объемных данных

Я пытаюсь создать набор необработанных объемных данных, состоящих из геометрических фигур. Дело в том, чтобы использовать объемное моделирование лучей для проецирования их в 2D, но сначала я хочу создать объем вручную.

Геометрия состоит из одного цилиндра, который находится в середине объема, вдоль оси Z, и двух меньших цилиндров, расположенных вокруг первого, возникающих в результате вращения вокруг осей.

Вот моя функция до сих пор:

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));

% ...

Идея состоит в том, что первый цилиндр создается, а затем «разрезается» в соответствии со значением оси Z, чтобы определить его высоту. Другой цилиндр создается с использованием отношения A 2 + B 2 = R 2, где A и B вращаются соответственно с использованием матриц вращения только вокруг осей x и y, используя R y (θ) R x (φ), как описано здесь.

До сих пор кажется, что все работает, потому что я реализовал код (проверенный, что он работает хорошо) для отображения проекции, и кажется, что цилиндры имеют правильное вращение, когда они не «обрезаны» с бесконечной высоты.

Я вычисляю N, который представляет собой вектор [0 0 1], также известный как ось Z, повернутый так же, как и цилиндр. Затем я нахожу две точки P на тех же расстояниях, на которых я хочу, чтобы были края цилиндра, и вычисляю уравнения плоскости T в соответствии с этими точками и вектором нормали. Наконец, я стригусь в соответствии с этим равенством. Или, по крайней мере, я думаю, что делаю, потому что после обрезки я обычно ничего не получаю (каждое значение равно нулю). Или, лучшее, что я мог получить, когда экспериментировал, это цилиндры обрезаны, но плоскости верха и низа не были хорошо ориентированы.

Я был бы признателен за любую помощь или исправления в моем коде, потому что я изучал уравнения геометрии и не могу найти, в чем ошибка.

Изменить: это быстрый снимок экрана объекта, который я пытаюсь создать. ПРИМЕЧАНИЕ: цилиндры непрозрачны в данных об объеме, вся внутренняя часть считается однородным материалом.

набор цилиндров


person George Aprilis    schedule 22.01.2013    source источник
comment
Может, набросок поможет.   -  person John Alexiou    schedule 22.01.2013
comment
Я добавил скриншот того, что пытаюсь создать.   -  person George Aprilis    schedule 23.01.2013
comment
Цилиндры слились воедино или между ними есть зазор.   -  person John Alexiou    schedule 23.01.2013
comment
Вначале я создаю бесконечные цилиндры, а затем хочу обрезать их с начальной точкой P, определенной как P = rad2*N + [ centerX centerY centerZ];. Таким образом, плоскость, которая на самом деле является нижней окружностью цилиндра, касается первого цилиндра, когда оси маленьких цилиндров горизонтальны.   -  person George Aprilis    schedule 23.01.2013


Ответы (1)


Думаю вместо:

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

вы должны попробовать следующее в обоих местах:

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

Умножение на N учитывает направление оси 2-го цилиндра, что вы уже сделали чуть выше этого шага.

person Spectre    schedule 19.03.2013
comment
Я попробовал ваше предложение, но оно не работает. Это дает непонятные результаты. Я также не уверен в правильности такого утверждения, как cyl2(T<0) = 0; Может быть, уравнения правильные, но обрезка неправильная? В любом случае спасибо за вашу помощь. - person George Aprilis; 19.03.2013