如何用Matlab在球面画出一个可见点?
首先,我们用sphere球函数计算绘出单位球的x,y,z数据;
其二,根据球半径r,计算球半径为r的x,y,z数据;
其三,使用surf函数绘制其球面。
最后,用hold on命令和plot3函数将球面上的一个点x1,y1,z1绘制在图像上。
实现代码:
[X,Y,Z] = sphere;? %用于绘出单位球的x,y,z数据
r = 5;? %球半径
X2 = X * r;
Y2 = Y * r;
Z2 = Z * r;
surf(X2,Y2,Z2)? %球半径为r = 5的球面
hold on %在同一图像增加其他图形
plot3(-3.5355,-3.5355,0.7822,'rp') %绘制球面上的一个点
axis equal
xlabel('x'),ylabel('y'),zlabel('z');
执行结果
编了一个简单的程序,供参考。
按照题意,应该就是在圆内生成随机点,然后看该点落在矩形区域内的概率。
感觉设置N和R两个参数其实没必要,直接进行N*R次模拟应该就可以了。
生成随机数的方式存在一定的问题。题中并没有指定随机数的分布规律,这里按照和圆心距离均匀分布、角度也均匀分布处理。这样似乎和射门没什么关系了,因为射门不太可能是这样的规律。另外,尽管沿径向和角度都是均匀分布的,并不意味着在整个圆内分布是均匀的(靠近圆心的位置更密集)。
参考代码:
%?参数输入d?=?inputdlg({'随机进球数N'?'试验次数R'},'试验设置',1,{'1000'?'100'});
if?isempty(d),?return,?end
N?=?round(str2double(d{1}));
R?=?round(str2double(d{2}));
L?=?4;
W?=?2;
D?=?sqrt(L^2+W^2);
%?绘图
clf
t?=?linspace(0,2*pi,200);
plot(D/2*cos(t),D/2*sin(t),'linewidth',2);
hold?on
patch([-1?1?1?-1]*L/2,[-1?-1?1?1]*W/2,'c','Facealpha',0.3)
h?=?plot(NaN,NaN,'.');
axis?equal
%?模拟
P?=?zeros(R,1);
for?n?=?1?:?R
r?=?rand(N,1)*D/2;
t?=?rand(N,1)*2*pi;
x?=?r.*cos(t);
y?=?r.*sin(t);
P(n)?=?sum(?abs(x)?<=?L/2?&?abs(y)?<=?W/2?)?/?N;
set(h,'xdata',x,'ydata',y);
drawnow
end
%?计算概率
p?=?mean(P)
function?spheres
clc,clear;
n=50;?%球的个数
x1=0;x2=100;?%x轴范围
y1=0;y2=100;?%y轴范围
z1=0;z2=20;%z轴范围
r=2;%球的半径
A=[x2-x1;y2-y1;z2-z1];
A=A-2*r;
centre=zeros(3,n-1);%保存圆心坐标
for?i=1:n
c=rand(3,1);
c=c.*A;?%圆心坐标
c=c+[x1;y1;z1]+r;
if?i==1
[x,y,z]?=?ellipsoid(c(1),c(2),c(3),r,r,r);
surf(x,y,z,ones(size(x)))?%画出来球
hold?on
else
s=0;
while(s==0)
c=rand(3,1);
c=c.*A;%圆心坐标
c=c+[x1;y1;z1]+2;
s=judge(i,c,centre,r);%判断圆心是否可以?即新画出的球不会与之前的重叠
end
[x,y,z]?=?ellipsoid(c(1),c(2),c(3),r,r,r);
surf(x,y,z,ones(size(x)))?%画出来球
hold?on
end
end
axis([0?100?0?100?0?20]);
function?s=judge(i,c,centre,r)
for?j=1:i-1
temp=centre(:,j);
f=c-temp;
d=norm(f,2);
if?d<2*r
s=0;?%表示新圆心不可以在c表示的点
return
end
end
s=1;%表示新圆心可以
这里的半径 r=2 ?你可以在第七行设置为1?
画球面很简单。
figure;
hold on;
sphere;
axis equal;
画正方体可以像下面画。
fm = [1 2 6 5; 2 3 7 6; 3 4 8 7; 4 1 5 8; 1 2 3 4; 5 6 7 8];
vm = [0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1];
figure;
hold on;
patch('Vertices',vm,'Faces',fm, 'FaceVertexCData',hsv(6),'FaceColor','flat'); view(-37.5, 30);
axis equal;
你可以运行看下。
将最近的三个点用直线连接为一个三角形,由点是均匀分布知其为等边三角形,且任意相邻的三点都可连成一个等边三角形,于是这180个点就连成了一个正多边形,且它的顶点数是180
数学只存在5种正多边形,而其中没有顶点数是180的,见下表
面数棱数顶点数每面边数每顶点棱数
正4面体4?643?3
正6面体6?128?4?3
正8面体8?126?3?4
正12面体1230?20?5?3
正20面体2030?12?3?5
由此可知,这里的均匀分布是指向足球表面的点那样类似分布的
由12个正方形和30个六边形组成,那30个六边形是全等的
写了一个不是均匀分布的,供参考
参照地球的经纬度,每隔pi/10取值,经度取[0:pi/10:2*pi],纬度取[0:pi/10:pi],由于matlab计算时的舍入误差使结果偏大,故经纬度都取不到最大值,故共有9*20+1=181个点。
clear
clc
x=zeros(1,180);
y=zeros(1,180);
z=zeros(1,180);
for n=1:9
for k=0:19
x(20*n+k)=0.5*sin(pi*n/10)*cos(pi*k/10);
y(20*n+k)=0.5*sin(pi*n/10)*sin(pi*k/10); %坐标变换
z(20*n+k)=0.5*cos(pi*n/10);
end
end
x
y
z
scatter3(x,y,z,'*','r')
xlabel('x')
ylabel('y')
zlabel('z')
供参考
酱油+炮灰+探路的?
?
哥们 你的错误出在第四行,
z=sqrt(100-(x.^2+y.^2));
当x=5时,100-(5^2+8.6603^2)为负数,但matlab中sqrt函数自变量为负值不显示错误,而是输出一个复数,但绘图是不认复数的,所以出错。
你的问题是x在正负5的某一段区间内第四行有复数产生,绘图出现错误。
X, Y, Z, and C cannot be complex.
意识是X,Y,Z不能为复数。
正确的代码已经贴出来了,我就不重复了。