推导说明
为便于公式推导,本文仅以球心在坐标原点时进行推导,需要说明的是球心不在原点时,只需把已知条件的坐标减去球心坐标,等完成求解后再加上球心坐标即可!
推导:
在前面博客,已经给出了三点画圆的代码,观察函数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]