How to make 'far away' markers appear smaller (perspective)

3 views (last 30 days)
KAE on 30 Jul 2019
Commented: Star Strider on 30 Jul 2019
To make it easier to visually interpret 3D data when shown on a 2D surface like the computer screen, I would like to plot data so that far-away markers appear smaller and nearby markers appear larger. Choosing the 'Perspective' axes projection seems to make no difference in marker size,
plot3(rand(1,10), rand(1,10), rand(1,10), 'ko')
ax = gca;
ax.Projection = 'perspective';
To me, all makers appear to be the same size here.
Next I tried making the markers actual 3D spheres. This works but it's fussy, and it still doesn't meet my aim of making it easier to read a 2D picture of a 3D plot,
nFace = 200; % Radius of sphere in plot units
[x,y,z] = sphere(nFace); % Create a sphere which we will replicate
sphereScale = 50; % Need to scale values so that spheres appear small, like markers
% xyz locations of sphere centers
xCenter = rand(1,10)*sphereScale - sphereScale/2;
yCenter = rand(1,10)*sphereScale - sphereScale/2;
zCenter = rand(1,10)*sphereScale - sphereScale/2;
% Plot the spheres/makers
for iSphere = 1:length(xCenter) % Plot several spheres
s(iSphere) = surf(x + xCenter(iSphere),...
y + yCenter(iSphere),...
z + zCenter(iSphere));
hold on;
axis equal;
% Make spheres appear like smooth 3D markers
set(s, 'facecolor', [1 1 1]*0.8, 'facealpha', 1, 'edgecolor', 'none', 'clipping','off');
ax = gca;
ax.Projection = 'perspective'; % This should result in foreshortening in the plot
view(30, 15);
% Add lighting to make spheres appear 3D
h.FaceLighting = 'gouraud';
h.AmbientStrength = 0.3;
h.DiffuseStrength = 0.8;
h.SpecularStrength = 0.9;
h.SpecularExponent = 25;
h.BackFaceLighting = 'unlit';
I still can't tell which markers are 'nearer' and which are 'farther', though, so the 3D information in this plot is still hard to interpret visually.

Accepted Answer

Star Strider
Star Strider on 30 Jul 2019
One option is to use a sort of ‘inverse square’ size dimension scaling function.
Example —
x = rand(1,10);
y = rand(1,10);
z = rand(1,10);
scatter3(x, y, z, 10./(x.^2 + y.^2), 'ko')
ax = gca;
ax.Projection = 'perspective';
This uses scatter3 because it offers a simple way to specify the marker sizes. (You could also include ‘z.^2’ in the scaling calculation, however I opted to use ‘x’ and ‘y’ only.)
Note that this only works for a fixed orientation with (0,0,1) the closest point. The marker sizes remain fixed, and do not scale appropriately as you rotate the axes. If your axes are different from the [0,1] range that rand provides, you willl also have to scale the distances appropriately.
Star Strider
Star Strider on 30 Jul 2019
Thank you.
You can exaggerate it by increasing the power to which the vectors are raised, for example:
1./(x.^3 + y.^3)
There may be other nonlinear functions as well that will do this. I experimented with the ’inverse square’ idea simply to prove the concept.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!

Translated by