Clipping Surface Plots When Plotting Large Volumes
Show older comments
I am curious if anyone has experienced something like this before. I know that Matlab has various clipping options and I have played with those with no success. I am trying to create some graphics that include a fairly large plotting volume but want to zoom in on small features within that volume. What I am experiencing is once the objects at the extremes of the volumes are far enough apart from the origin of the plot, the plot starts to clip the graphic at the origin that I am interested in looking at, sometlimes clipping it out entirely. I have created a piece of sample code below that demonstrates this issue on my machine. I hope it isn't machine-specific and can be replicated on yours. Any assistance would be much appreciated.

clc; clear all; close all;
set(gcf,'renderer','opengl')
%generate test points
[theta phi]=meshgrid(-180:10:180,-180:10:180);
[a b]=size(theta);
iter=1;
pts(a*b,3)=0;
for i=1:a
for j=1:b
[x y z]=sph2cart(theta(i,j)*pi/180,phi(i,j)*pi/180,1);
pts(iter,:)=[x y z];
iter=iter+1;
end
end
[x y z]=sphere(30);
%define initial figure properties
figure(1)
set(gcf,'OuterPosition',[100 100 500 500],'Color','Black');
figureh=gcf;
axesh=gca;
set(axesh,'Parent',figureh);
set(gca,'Clipping','off','ClippingStyle','rectangle');
set(gcf,'Clipping','off');
xlim([-inf inf]);
ylim([-inf inf]);
zlim([-inf inf]);
axis off;
shading flat;
hold on;
p2=plot3(pts(:,1),pts(:,2),pts(:,3),'r.','Parent',axesh,'Clipping','off');
p1=surf(x,y,z,'EdgeColor','None','FaceColor',[.5 .5 .5],'Parent',axesh,'Clipping','off');
hold off;
light;
material dull;
cameratoolbar;
camproj perspective;
camva(120);
campos('manual');
campos([0.7997 -1.1424 1.0343]);
camtarget([1 0 .5]);
camup([0 0 1]);
% change the scalaar (50) to higher values to see total clipping of sphere
p2.XData=p2.XData*500;
p2.YData=p2.YData*500;
p2.ZData=p2.ZData*500;
drawnow;
5 Comments
A few fuzzy areas...
1) is your code supposed to generate the image you shared because it doesn't show the gray sphere at all after changing the p2 data.
2) "What I am experiencing is once the objects at the extremes of the volumes are far enough apart from the origin of the plot, the plot starts to clip the graphic at the origin that I am interested in looking at, sometlimes clipping it out entirely." I lose you at the underlined part. The origin is (0,0,0). Even if I restate the sentence as "..the plot starts to clip the graphic at the section that I am interested in...", it still doesn't make sense to me.
3) What exactly is the problem? Is the problem that the gray sphere disappears?
Due to the projection, camera angles, etc, it's difficult to guess what the goal is and what is preventing you from achieving that goal. If the problem is that the gray sphere disappears, that's easy to explain.
Adam
on 21 Sep 2021
Adam
on 21 Sep 2021
Adam Danz
on 21 Sep 2021
Ah... I see. The sphere is expanding outside of the frustum. I'm not at my laptop at the moment but I will reply with an answer tomorrow unless someone else beats me to it.
Adam
on 22 Sep 2021
Answers (1)
Adam Danz
on 22 Sep 2021
TL;DR: When the coordinates for the red-dotted sphere are expanded, the axis limits are updated. The new x-axis limits clip the sphere because the x-coordinate of the camera is within the range of x-coordinates of the sphere.
Solution: Either reset the x-axis limit after exansion or change the camera position.
Furthre reading: Scratchapixel is my go-to site for graphics, projection geometry, etc. This site came in handy for me when I was learning (still am learning) OpenGL.
Illustrating the problem
Generate the base figure before setting camera properties and before expanding the red-dot sphere. I've commented-out irrelevant lines of code and cleaned up some other sections where I've left comments.
% set(gcf,'renderer','opengl')
%generate test points % I REPLACED YOUR FOR-LOOPS
[theta phi]=meshgrid(-180:10:180,-180:10:180);
[x y z]=sph2cart(theta*pi/180,phi*pi/180,1);
pts = [x(:), y(:), z(:)];
[x y z]=sphere(30);
%define initial figure properties
figureh = figure(1); % ADDED FIG HANDLE OUTPUT
set(figureh,'Color','Black'); % REMOVED OUTERPOSITION PROPERTY; USE FIG HANDLE
% figureh=gcf;
% axesh=gca;
% set(axesh,'Parent',figureh);
axesh = axes(figureh); % CLEANER AND SIMPLER THAN ABOVE
set(axesh,'Clipping','off','ClippingStyle','rectangle'); % USE AX HANDLE
set(figureh,'Clipping','off'); % USE FIG HANDLE
% xlim([-inf inf]); % THIS DOES NOTHING
% ylim([-inf inf]); % THIS DOES NOTHING
% zlim([-inf inf]); % THIS DOES NOTHING
axis off;
shading flat;
hold on;
p2=plot3(pts(:,1),pts(:,2),pts(:,3),'r.','Parent',axesh,'Clipping','off');
p1=surf(x,y,z,'EdgeColor','None','FaceColor',[.5 .5 .5],'Parent',axesh,'Clipping','off');
axis equal % ADDED
% hold off;
light;
material dull;
% cameratoolbar;

To illustrate the desired camera position and target, I've added a blue square and yellow cross respectively. I've also added a YZ plane at the camera's x-location to show the camera's position relative to the sphere. This shows the camera's future position and target.
plot3(1, 0, .5, 'y+','LineWidth',2,'MarkerSize', 10)
plot3(0.7997, -1.1424, 1.0343, 'cs','LineWidth',2,'MarkerSize', 10)
patch(0.7997*[1,1,1,1],[-1 -1 1 1], [-1 1, 1 -1], 'w','FaceAlpha', .8)
view(33,33) % to show the other side of the plane

Now move the camera and examine the axis limits before expanding the red sphere.
view(3) % ADDED
camproj perspective;
camva(120);
% campos('manual'); % REDUNDANT
campos([0.7997 -1.1424 1.0343]);
camtarget([1 0 .5]);
camup([0 0 1]);
xl = xlim % = [-1 1]
yl = ylim % = [-1.1424 1]
zl = zlim % = [-1 1.0343]

Now expand the red sphere and examine the axis limits again.
p2.XData=p2.XData*25;
p2.YData=p2.YData*25;
p2.ZData=p2.ZData*25;
% drawnow;
xlim % = [-25 25]
ylim % = [-25 25]
zlim % = [-25 25]

Return the axis limits to their original values before expansion.
xlim(xl)
ylim(yl)
zlim(zl)

Alternatively, move the camera position back a bit,
axesh.CameraPosition(1) = 1;
7 Comments
Adam
on 22 Sep 2021
Adam Danz
on 24 Sep 2021
Does that happen after you've made any changes to your code based off of my answer?
Adam Danz
on 27 Sep 2021
> What happens when you increase the gain by a few orders of magnitude to something like 2500? At that point the entire point cloud disappears and I can't get it to rerender even after increasing the axes limits.
Think about what the code is doing, line-by-line, section-by-section. Here's the first section before setting camera properties and before expanding the red-dotted sphere. Look at the axis limits. They are all basically [-1,1].
[theta phi]=meshgrid(-180:10:180,-180:10:180);
[x y z]=sph2cart(theta*pi/180,phi*pi/180,1);
pts = [x(:), y(:), z(:)];
[x y z]=sphere(30);
figureh = figure(1);
% set(figureh,'Color','Black'); % LETS LEAVE THE FIG WHITE FOR THIS DEMO
axesh = axes(figureh);
set(axesh,'Clipping','off','ClippingStyle','rectangle');
set(figureh,'Clipping','off');
% axis off; % LET"S LEAVE THE AXES ON FOR THIS DEMO
shading flat;
hold on;
p2=plot3(pts(:,1),pts(:,2),pts(:,3),'r.','Parent',axesh,'Clipping','off');
p1=surf(x,y,z,'EdgeColor','None','FaceColor',[.5 .5 .5],'Parent',axesh,'Clipping','off');
axis equal
light;
material dull;
plot3(1, 0, .5, 'y+','LineWidth',2,'MarkerSize', 10)
plot3(0.7997, -1.1424, 1.0343, 'cs','LineWidth',2,'MarkerSize', 10)
patch(0.7997*[1,1,1,1],[-1 -1 1 1], [-1 1, 1 -1], 'w','FaceAlpha', .8)
view(33,33) % to show the other side of the plane
view(3)

Now, store the original axis limits and expand the red-dot sphere by a factor of 2500. It looks like the gray sphere is gone but look at the updated axis limits. They are all wider than [-2000,2000] while the inside sphere still has a diameter of 2 making it very small, too small to see. But you can still see the camera marker (cyan square) and camera target (yellow cross).
xl = xlim;
yl = ylim;
zl = zlim;
g = 2500;
p2.XData=p2.XData*g;
p2.YData=p2.YData*g;
p2.ZData=p2.ZData*g;

If you return the original axis limits that worked in my previous answer, you'll see the gray sphere but you will no longer see the very-much-larger red sphere because the axis limits are all within the red sphere space.
xlim(xl)
ylim(yl)
zlim(zl)

None of this should be surprising. Furthermore, given your camera angle and target, the bounds of the image are very sensitive to your axis limits (or vise-versa: given you axis limits, the bounds of the image are very sensitive to the camera position & target).
To demonstrate this, I've increased the number of red dots using [theta,phi]=meshgrid(-180:1:180,-180:1:180) and manually zoomed into the center and manually rotated so that the target (blue cross) and camera position (cyan square) are aligned. This was done before setting the camera position & target. This shows the line of sight of the camera. Depending on your final axis limits, you could be staring at an empty space and completely miss both the gray sphere and all of the red dots. Moving forward, it would be helpful to review what a "viewing frustum" is. The link I provided in my answer is a great starting point.

Adam
on 27 Sep 2021
The position of the camera and target and shown in the plot below along with the line of sight of the camera. The code was copied from your comments above with the exception of lines where I've added comments.
g=6350;
[x y z]=sphere(90);
figureh = figure();
axesh = axes(figureh);
set(axesh,'Clipping','off','ClippingStyle','rectangle');
set(figureh,'Clipping','off');
axis off; hold on; axis equal;
im=imread('https://cdn11.bigcommerce.com/s-5luen2shhj/images/stencil/original/products/151/414/physical_earth_satellite_image_mural_lg__85186.1560352839.jpg?c=2&imbypass=on&imbypass=on');
earth=warp(x*g,y*g,z*g,rot90(rot90(im)));
set(earth,'Clipping','off');
cpos = [g+100 0 0]; % SPECIFY CAMERA POSITION
ctarg = [0 0 g]; % SPECIFY CAMERA TARGET
box on % VIEW AXES BOX
grid on % VIEW GRID
xlabel('x'); ylabel('y'); zlabel('z') % VIEW AXES LABELS
axis on % VIEW AXES
plot3(cpos(1), cpos(2), cpos(3), 'bs',... % SHOW CAM POSITION
'markersize', 12, 'linewidth', 3, ...
'DisplayName', 'CamPos')
plot3(ctarg(1), ctarg(2), ctarg(3), 'm*', ... % SHOW CAM TARGET
'markersize', 12, 'linewidth', 3, ...
'DisplayName', 'CamTarget')
plot3([cpos(1);ctarg(1)],[cpos(2);ctarg(2)], ... % SHOW LINE OF SIGHT
[cpos(3);ctarg(3)], 'y--', 'LineWidth', 3, ...
'DisplayName','LineOfSight')
legend('location','bestoutside') % ADD LEGEND
view(10,35) % VIEW ADDED MARKERS
alpha(.6) % ADD TRANSPARENCY TO SEE LINE OF SIGHT
It appears that you'd like to point the camera down upon earth at a very close distance to earth's surface. Just to see the viewing angle head-on, I've set the viewing angle and zoomed in a bit below. You can see the underlying axes with orthographic projection and since the earth is partially transparent, you can see the other side of the earth.
view(90, -45)
xlim([3624.7 6810.5])
ylim([-1242.9 1269.7])
zlim([-1243.5 1269.2])

However, when you apply your camera and axes properties, the earth is clipped an you see the other side of the earth. The reason why is 1) the near clipping plane cuts into the earth and 2) your axis limits contain the other side of the earth. I don't know enough about how openGL is applied to Matlab graphics to provide a more technical answer but hopefully my rinky dink drawing below will illustrate my explanation. The red outline is the (poorly drawn) frustum laying along the XZ axis (not to scale).

One way to fix this is the restrict the axis limits to elimiate the "other side" of the earth. For example, the camera target x-coordinate is 0 so the lower x-axis-limit can be set to 0 which solves the problem.
Continuing from the first block of code above,
camproj perspective;
campos(cpos);
camtarget(ctarg);
camva(60);
cameratoolbar;
alpha(1) % REMOVE TRANSPARENCY
axesh.XLim(1) = 0; % SPECIFY AXIS LIMS

Adam
on 29 Sep 2021
What motivated me to change the lower access limit was to eliminate seeing the far side of Earth but I don't know why that changes the near clipping plane.
I've worked with perspective projections in the past but have never thoroughly investigated it's implementation in matlab.
Perhaps these links may be helpful and if you ever get to the bottom of it, I'd love to hear what you find.
Categories
Find more on Camera Views in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




