У меня есть код, который анимирует точки, движущиеся в случайных направлениях в 2D-пространстве (оси x и y). Я попытался создать 3-е измерение (ось Z) с использованием сферических координат. Чтобы нарисовать и отобразить точки в 3D-пространстве, я использовал функцию moglDrawDots3D Psychtoolbox, так как она принимает 3D-координаты XYZ, но я все еще получаю 2D-анимацию, точки на z не появляются. Я понятия не имею о причине. Я очень новичок в Matlab и анимации, я был бы очень признателен за ваши отзывы и понимание. Я попытался объяснить свой код шаг за шагом ниже для ясности. Заранее спасибо за вашу помощь!
PS: Использование Psychtoolbox не является обязательным, если у вас есть другое решение, я был бы рад попробовать его.
AssertOpenGL;
InitializeMatlabOpenGL;
display = OpenWindow()
dots.nDots = 531; % number of dots
dots.color = [255,255,255]; % color of the dots
dots.size = 10; % size of dots (pixels)
dots.center = [0,0,0]; % center of the field of dots (x,y,z)
dots.apertureSize = [50.8,28.5,50.8]; % size of rectangular aperture [w,h,depth] in degrees
Во-первых, случайное положение в апертуре для каждой из точек. 'dots.x' и 'dots.y' будут содержать позиции x и y для каждой точки.
[dots.x,dots.y,dots.z] = CreateUniformDotsIn3DFrustum(dots.nDots, 25, 1/screen_ratio, 0.1, 100);
Затем я преобразовал эти положения точек из визуального угла в координаты пикселей, используя созданную функцию 'angle2pix'.
tmp = Screen('Resolution',0); % (1) Screen's 'Resolution' function determine the screen resolution.
display.resolution = [tmp.width,tmp.height];
display.width = 50.8; % (2) Width of the screen in cm.
display.dist = 50; % (3) Distance of the screen from the observer in cm.
Это генерирует позиции пикселей, но они центрируются в [0,0], что является верхним левым углом.
pixpos.x = angle2pix(display,dots.x); % Convert the x position of the dots from visual angle to pixel.
pixpos.y = angle2pix(display,dots.y); % Convert the y position of the dots from visual angle to pixel.
pixpos.z = ones(1, dots.nDots) * -1;
Я определил некоторые параметры времени и движения для анимации.
dots.speed = 3; % degrees/second
dots.duration = 10; % seconds
dots.theta_deg = randi(360,1,dots.nDots); % degrees
dots.phi_deg = 30; % degrees
dots.theta_rad = dots.theta_deg * pi /180; % direction converted to radians
dots.phi_rad = dots.phi_deg * pi /180; % direction converted to radians
Я рассчитал расстояние, пройденное точкой, определив положения x, y и z, используя сферические координаты, а затем их производную.
dx = dots.speed* sin(-dots.phi_rad-dots.theta_rad)/display.frameRate;
dy = -dots.speed* cos(dots.phi_rad + dots.theta_rad)/display.frameRate;
dz = -dots.speed*cos(dots.theta_rad)/display.frameRate;
Я пытаюсь поместить точки в апертуру, вычисляя левый, правый верх, низ и глубину (вперед и назад) апертуры (в градусах).
Общее количество кадров для анимации определяется продолжительностью (в секундах), умноженной на частоту кадров (кадров в секунду). Функция secs2frames выполняет вычисление
nFrames = secs2frames(display,dots.duration);
l = dots.center(1)-dots.apertureSize(1)/2;
r = dots.center(1)+dots.apertureSize(1)/2;
b = dots.center(2)-dots.apertureSize(2)/2;
t = dots.center(2)+dots.apertureSize(2)/2;
d_forward = dots.center(3)- dots.apertureSize(3)/2;
d_backward = dots.center(3)+ dots.apertureSize(3)/2;
Новые случайные стартовые позиции
[dots.x,dots.y,dots.z] = CreateUniformDotsIn3DFrustum(dots.nDots, 25, 1/screen_ratio, 0.1, 100);
Заставьте точки двигаться
try
for i=1:nFrames
%convert from degrees to screen pixels
pixpos.x = angle2pix(display,dots.x)+ display.resolution(1)/2;
pixpos.y = angle2pix(display,dots.y)+ display.resolution(2)/2;
pixpos.z = ones(1, dots.nDots) * -1;
moglDrawDots3D(display.windowPtr, [pixpos.x;pixpos.y;pixpos.z],dots.size, dots.color, dots.center,1);
обновить положение точки
dots.x = dots.x + dx;
dots.y = dots.y + dy;
dots.z = dots.z + dz;
Переместите точки, которые находятся за пределами апертуры, назад на одну ширину апертуры
dots.x(dots.x<l) = dots.x(dots.x<l) + dots.apertureSize(1);
dots.x(dots.x>r) = dots.x(dots.x>r) - dots.apertureSize(1);
dots.y(dots.y<b) = dots.y(dots.y<b) + dots.apertureSize(2);
dots.y(dots.y>t) = dots.y(dots.y>t) - dots.apertureSize(2);
dots.z(dots.z<d_forward) = dots.z(dots.z<d_forward) + dots.apertureSize(3);
dots.z(dots.z>d_backward) = dots.z(dots.z>d_backward) - dots.apertureSize(3);
Screen('Flip',display.windowPtr);
end
catch ME
Screen('CloseAll');
rethrow(ME)
end
Screen('CloseAll');
dz
всегда равно нулю, или соотношение сторон таково, что, хотя движение в направлении z есть, оно настолько мало по сравнению с x и y кажется, что он не движется). Я очень сомневаюсь, что на ваш вопрос можно ответить в его нынешнем виде. Можно ли опубликовать работающий пример? Вам нужно будет либо включить все вспомогательные функции, либо избегать их использования (вместо этого используя некоторые приближения). См. также: минимально воспроизводимый пример. - person Dev-iL   schedule 26.06.2019