You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 08:32:35