【问题标题】:(Satellite on orbit) - Create the tangent cone from point to sphere(轨道上的卫星) - 创建从点到球的切锥
【发布时间】:2020-11-17 18:35:41
【问题描述】:

我正在尝试绘制一个圆锥体,连接到 Matlab 中的球体。我的点 [x1,y1,z1] 在球体 [x2,y2,z2] 之外,半径为 R,我想要它成为圆锥的顶部,由切线创建。

在这张照片上,您可以看到我的想法:

您可以在下面看到我已经完成的工作。我使用它来标记地球表面的一部分,从轨道上的卫星位置可见。不幸的是,这张图片中的圆锥是近似的,我需要创建一个精确的,与表面相连。就目前而言,它不仅不准确,而且还在它之下。

我正在使用这个简单的代码创建球体(我跳过了将地图放在上面的部分,它只是一个图像):

r = 6371.0087714;
[X,Y,Z] = sphere(50);
X2 = X * r;
Y2 = Y * r;
Z2 = Z * r;
surf(X2,Y2,Z2)
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.FaceLighting = 'phong';
figure();
globe = surface(X2,Y2,Z2,props);

假设我有 3D 中的单点:

plot3(0,0,7000,'o');

我怎样才能创建这样一个圆锥体?

【问题讨论】:

    标签: matlab 3d geometry astronomy satellite


    【解决方案1】:

    这里有两个不同的问题:

    1. 如何计算圆锥尺寸?
    2. 如何绘制 3D 圆锥的侧面?

    计算圆锥尺寸

    假设球心位于[0 0 0]:

    d = sqrt(Ax^2+Ay^2+Az^2);
    l = sqrt(d^2-rs^2);
    t = asin(rs/d);
    h = l * cos(t);
    rc = l * sin(t);
    

    绘制圆锥

    以下函数返回圆锥侧面的坐标,给出顶点、轴方向、底半径和高度,以及侧面的数量。

    function [X, Y, Z] = cone3(A, V, r, h, n)
    % A: apex, [x y z]
    % V: axis direction, [x y z]
    % r: radius, scalar
    % h: height, scalar
    % n: number of lateral surfaces, integer
    % X, Y, Z: coordinates of lateral points of the cone, all (n+1) by 2. You draw the sphere with surf(X,Y,Z) or mesh(X,Y,Z)
    v1 = V./norm(V);
    B = h*v1+A;
    v23 = null(v1);
    th = linspace(0, 2*pi, n+1);
    P = r*(v23(:,1)*cos(th)+v23(:,2)*sin(th));
    P = bsxfun(@plus, P', B);
    zr = zeros(n+1, 1);
    X = [A(1)+zr P(:, 1)];
    Y = [A(2)+zr P(:, 2)];
    Z = [A(3)+zr P(:, 3)];
    end
    

    结果

    rs = 6371.0087714; % globe radius
    A = rs * 2 * [1 1 1]; % sattelite location
    V = -A; % vector from sat to the globe center
    % calculating cone dimensions
    d = norm(A); % distance from cone apex to sphere center
    l = (d^2-rs^2)^.5; % length of generating line of cone
    sint = rs/d; % sine of half of apperture
    cost = l/d; % cosine of half of apperture
    h = l * cost; % cone height
    rc = l * sint; % cone radius
    
    % globe surface points
    [XS,YS,ZS] = sphere(32);
    % cone surface points
    [XC, YC, ZC] = cone3(A, V, rc, h, 32);
    
    % plotting results
    hold on
    surf(XS*rs,YS*rs,ZS*rs, 'facecolor', 'b', 'facealpha', 0.5, 'edgealpha', 0.5)
    surf(XC, YC, ZC, 'facecolor', 'r', 'facealpha', 0.5, 'edgealpha', 0.5);
    
    axis equal
    grid on
    

    为卫星制作动画

    动画对象的最简单方法是通过clf 清除整个图形并在新位置再次绘制对象。但是一种更有效的方法是在每一帧中绘制一次所有对象,只更新移动对象的定位数据:

    clc; close all; clc
    rs = 6371.0087714; % globe radius
    r = rs * 1.2;
    n = 121;
    t = linspace(0, 2*pi, n)';
    % point on orbit
    Ai = [r.*cos(t) r.*sin(t) zeros(n, 1)];
    
    [XS,YS,ZS] = sphere(32);
    surf(XS*rs,YS*rs,ZS*rs, 'facecolor', 'b', 'facealpha', 0.5, 'edgealpha', 0.5)
    hold on
    [XC, YC, ZC] = cone3(Ai(1, :), Ai(1, :), 1, 1, 32);
    % plot a cone and store handel of surf object
    hS = surf(XC, YC, ZC, 'facecolor', 'r', 'facealpha', 0.5, 'edgealpha', 0.5);
    
    for i=1:n
        % calculating new point coordinates of cone
        A = Ai(i, :);
        V = -A;
        d = norm(A);
        l = (d^2-rs^2)^.5;
        sint = rs/d;
        cost = l/d;
        h = l * cost;
        rc = l * sint;
        
        [XC, YC, ZC] = cone3(A, V, rc, h, 32);
        % updating surf object
        set(hS, 'xdata', XC, 'ydata', YC, 'zdata', ZC);
        pause(0.01); % wait 0.01 seconds
        drawnow(); % repaint figure
    end
    

    另一个包含 3 颗轨道卫星的样本:

    【讨论】:

    • 谢谢!为什么会有l = (d^2-rs^2)^.5; 为什么你需要这个.^5?
    • @KamilSerafin 这就是勾股定理:d^2 = rs^2+l^2。
    • @KamilSerafin 也许您对由 0.5 而不是 5 提供支持的语法感到困惑。在大多数语言中可以消除零。
    • 对,我现在可以看到了!您知道如何删除创建的圆锥吗?我正在创建动画,每次迭代后我都必须创建新的锥体并从图中删除前一个锥体。我试过使用delete [XC,YC,ZC],但旧的锥体还在里面(几秒钟后我有数百个)。我怎样才能破坏以前的锥体?
    • @KamilSerafin 实际上我在发布此内容后的前几天制作了动画。我清理了我的代码并添加了一个示例。
    猜你喜欢
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多