球面上绘制圆matlab仿真

 推导说明   

为便于公式推导,本文仅以球心在坐标原点时进行推导,需要说明的是球心不在原点时,只需把已知条件的坐标减去球心坐标,等完成求解后再加上球心坐标即可!

推导:

在前面博客,已经给出了三点画圆的代码,观察函数generateCircle可知,若要画圆,我们只需要知道圆的圆心,圆所在平面的x方向向量以及y方向向量。

接下来,我们把工作重点放到求上述三个量上面,假定球为球心在坐标原点的单位球R=1,我们需要在球上 rs=[0.75,-0.17,0.64] 的位置画一个 15° 的圆,则

由已知可知,该圆的半径为: r=R*sin(15/180*pi);

该圆所在平面的方向向量为:cc=rs=[0.75,-0.17,0.64]

那么,过原点且与该圆所在平面平行的平面方程为:rs(1)*x+rs(2)*y+rs(3)*z=0

那么,在该平面随便取一个向量作为x轴的方向向量,如:nx=[1,1,-(rs(1)+rs(2))/rs(3)]

那么,根据叉乘规则,y轴的方向向量为:ny=cross(rs,nx);

此外,我们知道,圆心所在的位置在rs与圆心连线的直线上,根据球的参数方程可得,圆心所在的球面半径为:rr=R*cos(15/180*pi)

绘制球面的代码:

function drawsphere(a,b,c,R)
%% 绘制球面
% 以(a,b,c)为球心,R为半径

    % 生成数据
    [x,y,z] = sphere(20);

    % 调整半径
    x = R*x; 
    y = R*y;
    z = R*z;

    % 调整球心
    x = x+a;
    y = y+b;
    z = z+c;

    % 使用mesh绘制
%     figure;
%     axis equal;
    mesh(x,y,z);

    % 使用surf绘制
%     figure;
%     axis equal;
%     surf(x,y,z);
end

生成圆上点的代码

%% 生成圆上的点
% cp 圆心,R 圆半径,a圆平面的x轴方向向量,b圆平面的y轴方向向量,num 插值点个数
function xyz=generateCircle(cp,R,a,b,num)
    xyz=[];
    i=linspace(0,2*pi,num);
    x=cp(1) + R*cos(i)*a(1) +R*sin(i)*b(1);
    y=cp(2) + R*cos(i)*a(2) +R*sin(i)*b(2);
    z=cp(3) + R*cos(i)*a(3) +R*sin(i)*b(3);
    xyz=[x',y',z'];
end

直角坐标到球面坐标的转换

function xyz=sp2dikaer(azimuth,elevation,r)
    x = r .* cos(elevation) .* cos(azimuth);
    y = r .* cos(elevation) .* sin(azimuth);
    z = r .* sin(elevation);
    xyz=[x,y,z];
end

参考自matlab官网

测试代码:


clc;clear all;close all;
rs=[0.75,-0.17,0.64];
a=0;
b=0;
c=0;
R=1;
flag=0;
drawsphere(a,b,c,R);
hold on;
plot3(rs(1),rs(2),rs(3),'rp');

%% 圆的半径
r=R*sin(15/180*pi);
th=0:0.01:2*pi;
azimuth=atan2(rs(2),rs(1));
elevation=atan2(rs(3),sqrt(rs(2)^2+rs(1)^1));
% xyz=sp2dikaer(azimuth,elevation,R)

nx=[1,1,-(rs(1)+rs(2))/rs(3)];
ny=cross(rs,nx);
nx=nx/norm(nx);
ny=ny/norm(ny);
rs1=sp2dikaer(atan2(rs(2),rs(1)),atan2(rs(3),sqrt(sum(rs(1:2).^2))),R*cos(15/180*pi));
xyz=generateCircle(rs1,r,nx,ny,100);
plot3(xyz(:,1),xyz(:,2),xyz(:,3),'r', 'LineWidth',2);



飞舞的哲技术交流邮箱[email protected]

你可能感兴趣的:(matlab,matlab,开发语言)