Need some help on moving spheres in 3D axes!!
1 次查看(过去 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
0 个评论
回答(1 个)
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
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Earth and Planetary Science 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!