MATLAB中3D可视化日食遭遇近平面裁剪问题及求解
MATLAB中3D日食可视化的近平面裁剪问题及通用解决方案需求
我尝试在MATLAB中通过将太阳和月球建模为球体、将相机置于地球位置并沿轴对齐的方式,3D可视化日食。使用真实距离参数时,月球无法渲染,经排查推测是近平面裁剪导致。现寻求通用解决方案,实现相机附近小型物体的可视化。
相机远离太阳时的渲染效果:
但将相机移至地球位置时,月球会消失。
复现问题的MATLAB代码
% 定义太阳、地球、月球的尺寸/位置,相机位于地球 sunRadius = 696340; % 太阳半径(单位:km) moonRadius = 1737; % 月球半径(单位:km) earthPosition = 149600000; % 日地中心距离(1天文单位) earthMoonDistance = 384400; % 地月距离(单位:km) moonPosition = earthPosition - earthMoonDistance; % 月球相对太阳的位置 % 将相机移离月球一点以避免近平面裁剪 camPosition = earthPosition*1.01; % 若将相机置于地球位置,月球会因近平面裁剪无法渲染: % camPosition = earthPosition; % 绘制太阳和月球球体并设置相机位置 figure; set(gcf, 'WindowState', 'maximized') hold on; axis equal; % 配置光照以优化可视化效果 lighting phong; light('Position', [1 1 1], 'Style', 'infinite'); % 在原点绘制太阳(黄色球体) [x_sun, y_sun, z_sun] = sphere(50); sun = surf(sunRadius * x_sun, ... sunRadius * y_sun, ... sunRadius * z_sun); set(sun, 'FaceColor', [1, 1, 0], 'EdgeColor', 'none'); % 绘制相对太阳位置的月球(灰色球体) [x_moon, y_moon, z_moon] = sphere(50); moon = surf(moonRadius * x_moon + moonPosition, ... moonRadius * y_moon, ... moonRadius * z_moon); set(moon, 'FaceColor', [0.5, 0.5, 0.5], 'EdgeColor', 'none'); % 设置相对太阳的相机属性 camproj('perspective') campos([camPosition, 0,0]); % 相机位置 camtarget([camPosition-1, 0, 0]); % 相机沿X轴朝向原点 camva(1); % 设置相机视角以放大日食
补充说明
正如@Edric所答,axis tight可解决原X轴对齐场景的问题,但仅因该场景下axis tight大幅缩小了3D绘图体积。若将所有对象沿向量[1,1,1]对齐,即使使用axis tight问题仍存在:
% 定义太阳、地球、月球的尺寸/位置,相机位于地球 sunRadius = 696340; % 太阳半径(单位:km) moonRadius = 1737; % 月球半径(单位:km) earthDistance = 149600000; % 日地中心距离(1天文单位) earthMoonDistance = 384400; % 地月距离(单位:km) moonDistance = earthDistance - earthMoonDistance; % 月球相对太阳的位置 directionVector = [1,1,1]; directionVector = directionVector/norm(directionVector); % 将相机移离月球一点以避免近平面裁剪 camPosition = earthDistance*1.004*directionVector; moonPosition = moonDistance*directionVector; earthPosition = earthDistance*directionVector; % 若将相机置于地球位置,月球会因近平面裁剪无法渲染: % camPosition = earthPosition; % 绘制太阳和月球球体并设置相机位置 figure; set(gcf, 'WindowState', 'maximized') hold on; axis equal; % 配置光照以优化可视化效果 lighting phong; light('Position', [1 1 1], 'Style', 'infinite'); % 在原点绘制太阳(黄色球体) [x_sun, y_sun, z_sun] = sphere(50); sun = surf(sunRadius * x_sun, ... sunRadius * y_sun, ... sunRadius * z_sun); set(sun, 'FaceColor', [1, 1, 0], 'EdgeColor', 'none'); % 绘制相对太阳位置的月球(灰色球体) [x_moon, y_moon, z_moon] = sphere(50); moon = surf(moonRadius * x_moon + moonPosition(1), ... moonRadius * y_moon + moonPosition(2), ... moonRadius * z_moon + moonPosition(3)); set(moon, 'FaceColor', [0.5, 0.5, 0.5], 'EdgeColor', 'none'); % 设置相对太阳的相机属性 camproj('perspective') campos(camPosition); % 相机位置 camtarget([0, 0, 0]); % 相机朝向原点 camva(1); % 设置相机视角以放大日食 axis tight
内容的提问来源于Stack Exchange,提问作者MountainDrew
相关产品推荐
相关产品推荐

