Need some help on moving spheres in 3D axes!!

12 次查看(过去 30 天)
Hi guys. I'm trying to create a personalizable solar sistem and basically I got 2 problem:
The first and more important is than I can't move the planet on the orbit (the orbit are generated by the function updatePVA using semi explicit euler approx and I know that they work because I've already tried with marker), I know that I have to modify X,Y,ZDATA field of each planet but when I run, all planets disappear instead of move.
Can somebody help me??
That's my code.
clc; clear; close all;
%richiamo la funzione che contiene tutto il programma
AAA;
function AAA;
dt=0.1;
s=get(0,'ScreenSize');
w=800; m=400;
fig=figure('Position',[s(3)/2-w/2,s(4)/2-m/2, w,m]);
fig.Name='YOUR SOLAR SYSTEM';
fig.NumberTitle='off';
view(3);
b = gca;
set(b,'Color','black');
b.Position = [0.1 0.1 0.6 .85];
b.GridLineStyle = 'none';
b.XTick = [];
b.YTick = [];
b.ZTick = [];
%pianeti sistema solare
Sole =flipud(imread('Sole.jpg'));
Mercurio=flipud(imread('Mercurio.jpeg'));
Venere = flipud(imread('Venere.jpeg'));
Terra = flipud(imread('Terra.jpg'));
Marte = flipud(imread('Marte.jpg'));
Giove = flipud(imread('Giove.jpg'));
Saturno = flipud(imread('Saturno.jpeg'));
Urano = flipud(imread('Urano.jpeg'));
Nettuno = flipud(imread('Nettuno.jpeg'));
Plutone = flipud(imread('Plutone.jpeg'));
%texture extra per personalizzare
%Viola=flipud(imread('Viola.jpeg'));
%Cocomero=flipud(imread('Cocomero.jpeg'));
%NanaBianca =flipud(imread('NanaBianca.jpeg'));
%EsplosioneDiColori =flipud(imread('EsplosioneDiColori.jpeg'));
[X,Y,Z]= sphere(200);
bodies = initialConditions();
for i=1:length(bodies)
pianeta(i).X=bodies(i).p(1); %information about planet are defined in struct named bodies with position (x,y,z), radius ,mass(useless here)
pianeta(i).Y=bodies(i).p(2);
pianeta(i).Z=bodies(i).p(3);
pianeta(i).R=bodies(i).r;
pianeta(i).S=surface(pianeta(i).R.*X+pianeta(i).X,...
pianeta(i).R.*Y+pianeta(i).Y,...
pianeta(i).R.*Z+pianeta(i).Z);
pianeta(i).S.EdgeColor = 'none';
pianeta(i).S.FaceColor = 'texturemap';
end
axis equal;
axis([-3000 3000 -3000 3000 -3000 3000]);
%texture iniziali predefinite da poter modificare in seguito
pianeta(1).S.CData = Sole;
pianeta(2).S.CData = Mercurio;
pianeta(3).S.CData = Venere;
pianeta(4).S.CData = Terra;
pianeta(5).S.CData = Marte;
pianeta(6).S.CData = Giove;
pianeta(7).S.CData = Saturno;
pianeta(8).S.CData = Urano;
pianeta(9).S.CData = Nettuno;
pianeta(10).S.CData = Plutone;
inizia_personalizzazione = uicontrol('Style','pushbutton','String','inizia personalizzazione');%stile,scelta stile bottone , stringa ,scritta stringa
inizia_personalizzazione.Units = 'normalized';
inizia_personalizzazione.Position = [0.75 0.6 0.2 0.05];
inizia_personalizzazione.Callback = @button_pers_callback;
inizia_simulazione = uicontrol('Style','pushbutton','String','inizia simulazione');%stile,scelta stile bottone , stringa ,scritta stringa
inizia_simulazione.Units = 'normalized';
inizia_simulazione.Position = [0.75 0.4 0.2 0.05];
inizia_simulazione.Callback = @button_simulaz_callback;
button_fine = uicontrol('Style','pushbutton','String','fine programma');%stile,scelta stile bottone , stringa ,scritta stringa
button_fine.Units = 'normalized';
button_fine.Position = [0.86 0.01 0.134 0.038];
button_fine.Callback = @button_fine_callback;
function button_pers_callback(~,~)
set(inizia_personalizzazione,'visible','off');
set(inizia_simulazione,'visible','off');
menu_pers;
end
function menu_pers(~,~)
f1=gcf;
panel= uipanel(f1);
panel.Units='normalized';
panel.Position = [0.75 0.35 0.2 0.50];
popup_sceltapianeta=uicontrol('Style','popupmenu');
popup_sceltapianeta.Units='normalized';
popup_sceltapianeta.Position=[0.75 0.7 0.2 0.1];
popup_sceltapianeta.String='Pianeta1|Pianeta2|pianeta3|Pianeta4|Pianeta5|pianeta6|pianeta7';
popup_sceltapianeta.Callback=@popup_sceltapianeta_callback;
popup_texturepianeta=uicontrol('Style','popupmenu');
popup_texturepianeta.Units='normalized';
popup_texturepianeta.Position=[0.75 0.6 0.2 0.1];
popup_texturepianeta.String='Terra|Viola|Cocomero';
popup_texturepianeta.Callback=@popup_texturepianeta_callback;
stringa_nomepianeta = uicontrol('style','edit');
stringa_nomepianeta.Units='normalized';
stringa_nomepianeta.Position=[0.75 0.5 0.2 0.1];
stringa_nomepianeta.Callback=@text_nomepianeta_callback;
end
function button_fine_callback(src,~)
close(gcf)
end
function popup_sceltapianeta_callback(src,~)
src.Value
camlookat(pianeta(src));
return;
end
function button_simulaz_callback(~,~)
for tp=1:3000
% trova la forza gravitazionale tra due pianeti
for ii=1:(length(bodies)-1)
for jj=(ii+1):length(bodies)
[bodies(ii).f, bodies(jj).f] = updateF(bodies(ii), bodies(jj));
end
end
% update position, velocity, and acceleration, and reset force
%aggiorna posizione, velocità, accelerazione e resetta la forza
for ii=1:length(bodies)
[bodies(ii).p, bodies(ii).v, bodies(ii).a] = updatePVA(bodies(ii), dt);
bodies(ii).f = [0 0 0];
end
for tpp=1:length(bodies)
pianeta(tpp).S.XData= X+bodies(tpp).p(1)
pianeta(tpp).S.YData= Y+bodies(tpp).p(2)
pianeta(tpp).S.ZData= Z+bodies(tpp).p(3)
end
drawnow;
pause(0.1);
end
end
end

回答(1 个)

Ahmed Redissi
Ahmed Redissi 2021-4-15
Hi,
I worked on something similar before to create the Solar System in Matlab. First, I calculated the x, y, and z coordinates for each planet and moon at different points in time. Then I plotted the planet or moon and inserted a pause. Then, I deleted the plot so I can plot at the next time.
Here's a simiplified version of my code where only the Sun, Earth, and Moon are plotted in the animation:
clear
clc
close all
warning off
% Defining Parameters
nc = 1; % Number of Cycles
thetadeg = 0:2.5:360*nc;
theta = deg2rad(thetadeg);
L = length(theta);
s = 0; % Saving The Animation (s = 1)
w = 0.1; % Waiting Time (s)
filename = 'sun_earth_moon.gif';
circledeg = 0:2.5:360;
circles = deg2rad(circledeg);
% Sun
Rs = 0.25; % Sun Radius
[xstar,ystar,zstar] = sphere(50);
xstar = Rs*xstar;
ystar = Rs*ystar;
zstar = Rs*zstar;
% Earth
Dp3 = 1; % Earth Orbit Radius
Rp3 = 0.08; % Earth Radius
op3 = 1; % Earth Orbital Period
tiltp3 = 7; % Earth Orbital Tilt (Degress)
axisp3 = 'y';
[xp3,yp3] = pol2cart(theta,Dp3);
zp3 = zeros(1,L);
[xp3,yp3,zp3] = AxialTilt(xp3,yp3,zp3,tiltp3,axisp3);
% Moon
Dm1 = 0.2; % Moon Orbit Radius
Rm1 = 0.04; % Moon Radius
opm1 = 0.08; % Moon Orbital Period
tiltm1 = 5.15; % Moon Orbital Tilt (Degrees)
axism1 = 'y';
[xm1,ym1] = pol2cart(theta,Dm1);
zm1 = zeros(1,L);
[xm1,ym1,zm1] = AxialTilt(xm1,ym1,zm1,tiltm1,axism1);
lim = 1.5;
h = figure;
% Plotting The Orbits
orbitcolor = 'g'; % Orbits Color
plot3(xp3,yp3,zp3,orbitcolor)
axis([-lim,lim,-lim,lim,-lim/2,lim/2])
set(gca,'xtick',[])
set(gca,'ytick',[])
set(gca,'ztick',[])
set(gca,'Visible','off')
set(gca,'color','k')
set(gcf,'color','k')
set(gcf,'position',[0,0,1680,1200])
view(10,30)
hold on
% Plotting The Sun
surf(xstar,ystar,zstar,'FaceColor',[1,0.5,0],'LineStyle','none','EdgeAlpha',0);
for i = 1:L
% Plotting Earth
[xcp3,ycp3,zcp3] = CenterPoint(theta(i),op3,Dp3,tiltp3,axisp3);
[xplanet3,yplanet3,zplanet3] = PlotSphere(xcp3,ycp3,zcp3,Rp3);
fp3 = surf(xplanet3,yplanet3,zplanet3,'FaceColor',[0,0,1],'LineStyle','none','EdgeAlpha',0);
% Plotting Moon Orbit
xmd1 = xm1+xcp3; ymd1 = ym1+ycp3; zmd1 = zm1+zcp3;
pm1 = plot3(xmd1,ymd1,zmd1,orbitcolor);
% Plotting Moon
[xcm1,ycm1,zcm1] = CenterPoint2(theta(i),op3,Dp3,tiltp3,axisp3,opm1,Dm1,tiltm1,axism1);
[xmoon1,ymoon1,zmoon1] = PlotSphere(xcm1,ycm1,zcm1,Rm1);
fm1 = surf(xmoon1,ymoon1,zmoon1,'FaceColor',[0.5,0.5,0.5],'LineStyle','none','EdgeAlpha',0);
pause(w)
if s == 1
% Capture the plot as an image
frame = getframe(h);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
% Write to the GIF File
if i == 1
imwrite(imind,cm,filename,'gif','Loopcount',inf,'DelayTime',w);
else
imwrite(imind,cm,filename,'gif','WriteMode','append','DelayTime',w);
end
end
if i ~= L
delete(fp3);
delete(pm1);
delete(fm1);
end
end
hold off
function [xrot,yrot,zrot] = AxialTilt(x,y,z,tiltdeg,axis)
% x,y,z - Coordinates Before Tilt
% tiltdeg - Angle of Tilt (Degrees)
% axis - Axis of Tilt: 'x', 'y', or 'z'
% xrot,yrot,zrot - Coordinates After Tilt
tilt = deg2rad(tiltdeg);
Rx = [1,0,0;0,cos(tilt),-sin(tilt);0,sin(tilt),cos(tilt)];
Ry = [cos(tilt),0,sin(tilt);0,1,0;-sin(tilt),0,cos(tilt)];
Rz = [cos(tilt),-sin(tilt),0;sin(tilt),cos(tilt),0;0,0,1];
if axis == 'x'
temp = Rx*[x;y;z];
elseif axis == 'y'
temp = Ry*[x;y;z];
elseif axis == 'z'
temp = Rz*[x;y;z];
end
xrot = temp(1,:);
yrot = temp(2,:);
zrot = temp(3,:);
end
function [x,y,z] = CenterPoint(theta,op,D,tiltdeg,axis)
tilt = deg2rad(tiltdeg);
freq = 1/op;
if axis == 'y'
x = D*cos(freq*theta)*cos(tilt);
y = D*sin(freq*theta);
z = -D*cos(freq*theta)*sin(tilt);
elseif axis == 'x'
x = D*cos(freq*theta);
y = D*sin(freq*theta)*cos(tilt);
z = D*sin(freq*theta)*sin(tilt);
else
error('Please enter x or y for the axis as a string')
end
end
function [x,y,z] = PlotSphere(x0,y0,z0,R)
% x0,y0,z0 - Sphere Center Coordinates
% R - Sphere Radius
% x,y,z - Sphere Mesh
[x,y,z] = sphere(50);
x = x0+R*x;
y = y0+R*y;
z = z0+R*z;
end
function [x,y,z] = CenterPoint2(theta,op1,D1,tiltdeg1,axis1,op2,D2,tiltdeg2,axis2)
tilt1 = deg2rad(tiltdeg1);
tilt2 = deg2rad(tiltdeg2);
freq1 = 1/op1;
freq2 = 1/op2;
if axis1 == 'y'
x = D1*cos(freq1*theta)*cos(tilt1);
y = D1*sin(freq1*theta);
z = -D1*cos(freq1*theta)*sin(tilt1);
elseif axis1 == 'x'
x = D1*cos(freq1*theta);
y = D1*sin(freq1*theta)*cos(tilt1);
z = D1*sin(freq1*theta)*sin(tilt1);
else
error('Please enter x or y for the axis as a string')
end
if axis2 == 'y'
x = x+D2*cos(freq2*theta)*cos(tilt2);
y = y+D2*sin(freq2*theta);
z = z-D2*cos(freq2*theta)*sin(tilt2);
elseif axis2 == 'x'
x = x+D2*cos(freq2*theta);
y = y+D2*sin(freq2*theta)*cos(tilt2);
z = z+D2*sin(freq2*theta)*sin(tilt2);
else
error('Please enter x or y for the axis as a string')
end
end

类别

Help CenterFile Exchange 中查找有关 Earth and Planetary Science 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by