How to mask a circle in perspective projection?

3 ビュー (過去 30 日間)
Ma'ayan Gadot
Ma'ayan Gadot 2018 年 11 月 20 日
コメント済み: Ma'ayan Gadot 2018 年 11 月 27 日
Hi,
I simulate a 3-D scene using matlab camproj perspective.
This procedure creates a perspective projection of the shapes (triangles), but the stimuli coordinates remain in orthographic representation (world coordinates).
I want to mark all the triangles inside a circle. Using inpolygon, marke the triangles as if this was done in orthographic projection and not perspective.
See attached files for demostration.
Any ideas on how to get the triangles screen coordinates?
Thank you
  1 件のコメント
Bruno Luong
Bruno Luong 2018 年 11 月 20 日
編集済み: Bruno Luong 2018 年 11 月 20 日
What is "world coordinates"? What are those red triangles in the second picture? Where are the "dots"?

サインインしてコメントする。

採用された回答

Bruno Luong
Bruno Luong 2018 年 11 月 20 日
編集済み: Bruno Luong 2018 年 11 月 20 日
@Maayan please make an effort to give feedback to various answer/questions addressed to you.
Just update the persective code in this thread.
Perspective.png
Z = peaks;
x = 1:size(Z,2);
y = 1:size(Z,1);
[X,Y] = meshgrid(x,y);
figure(1);
clf
ax=subplot(1,2,1);
surface(X,Y,Z)
view(rand*360,(rand-0.5)*180)
camproj(ax,'perspective');
axis(ax,'equal');
drawnow;
CT = get(ax,'CameraTarget');
CP = get(ax,'CameraPosition');
% Get the camera closer in order to amphasize the 3D perspective effect
NewCP = CT + 0.2*(CP-CT);
set(ax,'CameraPosition',NewCP);
CP = get(ax,'CameraPosition');
CU = get(ax,'CameraUpVector');
cadeg = get(ax,'CameraViewAngle');
CT = CT(:);
CP = CP(:);
CU = CU(:);
ca = cadeg*pi/180;
%
c = CT-CP;
d = norm(c);
c = c / d;
u = CU - (c'*CU)*c;
u = u/norm(u);
p = cross(c,u);
R = [c,p,u];
Camera = struct('R', R, 'CP', CP);
[xcam, ycam] = CamProj(X, Y, Z, Camera);
[xc, yc] = CamProj(CT, Camera);
radius = 0.2;
incircle = (xcam-xc).^2+(ycam-yc).^2 < radius^2;
subplot(1,2,2);
plot(xcam(~incircle),ycam(~incircle),'.b',...
xcam(incircle),ycam(incircle),'.r');
hold on
rectangle('Position',[xc-radius yc-radius 2*radius 2*radius],'Curvature',[1 1],'EdgeColor','r')
axis equal
% This doesn't seem to crop the projection correctly
camyangle = sin(ca/2)*[-1 1];
camylim = [min(ycam),max(ycam)];
camxlim = [min(xcam),max(xcam)];
%%
function [xcam, ycam] = CamProj(varargin)
% Do perspective projection
% [xcam, ycam] = CamProj(X, Y, Z, Camera)
% [xcam, ycam] = CamProj(XYZ, Camera), XYZ is (3 x n) array
if nargin >= 4
[X,Y,Z,Camera] = deal(varargin{:});
sz = size(X);
XYZ = [X(:),Y(:),Z(:)]';
else
[XYZ,Camera] = deal(varargin{:});
[m,n] = size(XYZ);
if m~=3 && n==3
XYZ = XYZ.';
n = m;
end
sz = [1,n];
end
CPU = Camera.R'*(XYZ-Camera.CP);
XYcam = CPU(2:3,:)./CPU(1,:);
xcam = reshape(XYcam(1,:),sz);
ycam = reshape(XYcam(2,:),sz);
end % CamProj
  3 件のコメント
Bruno Luong
Bruno Luong 2018 年 11 月 22 日
編集済み: Bruno Luong 2018 年 11 月 22 日
For MATLAB version before R2016b, user needs to replace
XYZ-Camera.CP
with
bsxfun(@minus, XYZ, Camera.CP)
Ma'ayan Gadot
Ma'ayan Gadot 2018 年 11 月 27 日
Thank you very much!
Your response solvd the problem.

サインインしてコメントする。

その他の回答 (1 件)

Jan
Jan 2018 年 11 月 20 日
I assume the triangles are the "dots" and they are read, because they are inside a certain distance to the line through the center of the circle, which is normal in the plane of the circle.
The solution will be to calculate a 2D projection of the coordinates at first. This is done by the graphics renderer already, but not complicated by maths also. Afterwards the selection of the points inside the circle is trivial again.
This might help:
  1 件のコメント
Bruno Luong
Bruno Luong 2018 年 11 月 20 日
Read through the first link, it seems the projection is only valid in 'orthographic' projection mode, and not 'perspective' mode.
For persective the correct projection is answered yesterday in this thread

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCamera Views についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by