У Matlab нет простого готового способа настроить искажение перспективы проекции трехмерной фигуры, о которой я знаю. Итак, учитывая приведенный ниже код:
figure;
x1 = rand(1,10);
x2 = rand(1,10);
x3 = rand(1,10);
scatter3(x1,x2,x3,80,'o','filled'); hold on
ax = gca;
ax.Projection='perspective';
результаты не впечатляют:
Я пытался изменить ax.CameraTarget
, ax.CameraPosition
и т. д., но почти невозможно изменить «точку схода», чтобы она выглядела более искаженной, например. так:
Любая помощь в том, как достичь этого уровня контроля над внешним видом фигуры?
Спасибо!
Вы можете добиться этого, перейдя в режим «широкий угол», то есть выбрав большой CameraViewAngle
, перемещая камеру дальше к сюжету. Это дает вам некоторое искажение, как вы, возможно, знаете из широкоугольных объективов камеры.
В следующем коде я предположил, что камера находится в центре z
-уровня системы координат, а x
и y
-координаты смещены как раз на линии соединения между двумя крайними точками системы координат, сдвинутой назад на ее длину. . Остальное в основном "закон косинусов". Не стесняйтесь адаптировать положение камеры в пределах заданных разумных уровней, чтобы угол обзора оставался в диапазоне от 0 до 180 градусов, https://de.mathworks.com/help/matlab/ref/matlab.graphics. axis.axes-properties.html#budumk7-Просмотр). В этом примере предполагается, что угол обзора в плоскости x
-y
примерно такой же, как и в плоскости y
-z
. В противном случае нужно было бы расширить расчет и взять средний или максимальный угол обоих.
figure;
x1 = rand(1, 10) + 10;
x2 = rand(1, 10) + 15;
x3 = rand(1, 10) + 10;
scatter3(x1, x2, x3, 80, 'o', 'filled');
% get the axis limits
xax = xlim; yax = ylim; zax = zlim;
ax = gca;
ax.Projection = 'perspective';
% get the default camera target (where the cam looks at)
camTarget = get(ax, 'CameraTarget');
newCamPos = [ 2*xax(1)-xax(2) 2*yax(1)-yax(2) camTarget(3) ];
a = sqrt((xax(1)-newCamPos(1))^2 + (yax(2)-newCamPos(2))^2);
b = sqrt((xax(2)-newCamPos(1))^2 + (yax(1)-newCamPos(2))^2);
lsqr = (xax(2)-xax(1))^2 + (yax(2)-yax(1))^2;
angle = acos((lsqr - a^2 - b^2) / -(2*a*b)) *180/pi;
set(ax, 'CameraViewAngle', angle, ...
'CameraPosition', newCamPos);
Ты прав. Я просто немного обобщил и соответствующим образом отредактировал свой предыдущий ответ.
Большой! но решение кажется специфичным для ограничений, которые я указал? Например, каким будет значение CameraViewAngle и CameraPosition для следующей ситуации (или другой?). Большое спасибо! x1 = ранди([1 9],10); x2 = ранди([5 18],10); х3 = ранд (1,10); scatter3(x1,x2,x3,80,'o','заполненный')