Animating a pointmass sliding down a plane

7 views (last 30 days)
R.S.
R.S. on 12 Oct 2020
Commented: R.S. on 12 Oct 2020
Hey everyone, I would like to animate a pointmass that slides down an inclined plane.
So far that works but the distance between my pointmass and plane varies depending what kind of angle I enter.
Do you have any idea how to solve that?
I tried different ways to calculate the positon of my pointmass. Through linear Equations, cosine, sine, tangent but nothing worked.
Thanks in advance.
%% 2. Test-Programm zur Animation
clc;
close all;
clear;
%% Physikalische Parameter
Alpha = 70; %Chosen angle in [deg]
g = 9.81; %Chosen acceleration in [m/s²]
m = 12; %Chosen Mass [kg] (not needed yet)
H = 20; %Fall height
%% Randbedingungen berechnen
P1_X = 0;
P1_Y = 0;
P2_X = H/tand(Alpha);
P2_Y = -H;
P3_X = P1_X;
P3_Y = P2_Y;
Patch_X = ([P1_X P2_X P3_X]); %Corner points for generating Triangle
Patch_Y = ([P1_Y P2_Y P3_Y]);
b = 2*cosd(Alpha); %Y-Axis shift
s = P2_X/cosd(Alpha); %Distance the mass slides
a = g*sind(Alpha); %Acceleration in plane
tu = sqrt(2*s/a); %Duration of sliding
B = tu*25; %Number of "frames" that nee to be generated (25fps)
%% Orte und Zeitpunkte der Masse
%Some calculations I tried to define the positon of my mass
%D = s/1.5; %Distance I determined the mass will slide down
%L = 5;
%X_1 = (-1)*D*cosd(Alpha);
%Y_1 = D*sind(Alpha); % X and Y positon of the plane
%X_Ortho = L*sind(Alpha); %Point orthogonal to my plane
%Y_Ortho = L*cosd(Alpha);
%X_Start = X_1 + X_Ortho; %New plane that is orthogonal to my plane
%Y_Start = Y_1 + Y_Ortho;
t_z = tu/B; %Time interval between frames
t_f(1) = 0;
for i=1:(round(B)+1)
t_f(i+1) = t_f(i) + t_z; %Moments in time the frames are shown
end
for k=1:length(t_f)
s_t(k) = (1/2)*a*t_f(k)^2; %covered distance over time
z(1,k) = s_t(k)*cosd(Alpha); %X-Axis %calculation with the orthogonal plane (-1)*s_pk(k)*cosd(Alpha) + X_Ortho;
z(2,k) = tand((-1)*Alpha)*z(1,k)+b; %Y-Axis %s_pk(k)*sind(Alpha) + Y_Ortho;
end
%% Animation
q = 1;
Posx = 700;
Posy = 250;
width = 1100;
height = 1000;
fig = figure('Name', 'Punktmasse an der schiefen Ebene','NumberTitle','off','position', [Posx Posy width height], 'units', 'centimeters');
time = 0;
tic;
while time < tu
time = toc;
clf;
posDraw = interp1(t_f',z',time')'; %Interpolates Position of mass based on real time
hold on;
patch(Patch_X, Patch_Y,'green') %Generates the Triangle
fill(posDraw(1)+b+1.5*cos(0:0.01:2*pi), posDraw(2)+b+1.5*sin(0:0.01:2*pi), 'k')
axis equal;
axis off;
drawnow
end

Accepted Answer

J. Alex Lee
J. Alex Lee on 12 Oct 2020
Edited: J. Alex Lee on 12 Oct 2020
There's some inconsistency in whether you are treating the angle from vertical or horizontal (effectively). It may also be conceptually simpler to base all positions off of your ball's center as reference, so then you just shift your ramp down, and your ball center trajectory calculations can remain "clean".
Here's an implementation, also demonstrating how it is more efficient to draw things once then update their positions, rather than keep redrawing from scratch in the loop
clc;
close all;
clear;
% parameters
Alpha = 24; % Chosen angle from horizontal in [deg]
g = 9.81; % Chosen acceleration in [m/s²]
m = 12; % Chosen Mass [kg] (not needed yet)
H = 20; % Fall height [m]
R = 1.5; % radius of ball [m]
a = g*sind(Alpha); % component of acceleration along ramp
xTotal = H/tand(Alpha); % total distance of fall in x direction (to draw ramp)
dTotal = H/sind(Alpha); % total distance along ramp direction of fall
tEnd = sqrt(2*dTotal/a); % time it takes to fall the distance of ramp
% define trajectory functions in terms of ball center
% if you will extend these later for things like friction
% may be easier to move them into real functions
dsfcn = @(t)( 0.5*a*t.^2 ); % displacement vs time function, in plane direction
dxfcn = @(t)( cosd(Alpha)*dsfcn(t) );
dyfcn = @(t)( -sind(Alpha)*dsfcn(t) );
% Visualization
% equations w.r.t. horizontal direction x to visualize ramp and trajectory
trajfcn = @(x) (-1./cotd(Alpha)*x); % the trajectory of ball center
rampfcn = @(x) (-1./cotd(Alpha)*(x+R*sind(Alpha)) - R*cosd(Alpha)); % the ramp
% for drawing the ball
t = linspace(0,2*pi,100)';
xBall = R*cos(t);
yBall = R*sin(t);
% draw the objects once, edit their positions later
fig = figure(1);
ax = axes(fig,"DataAspectRatio",[1 1 1],"NextPlot","add");
h.ramp = fplot(rampfcn,[-2*R,xTotal+2*R],'-k','LineWidth',2);
h.ball = patch(xBall,yBall,'r','EdgeColor','r','FaceColor',[1 1 1]*0.8);
% visualize some other lines
fplot(trajfcn,[0,xTotal],':k','LineWidth',1)
xline(0,':')
yline(0,':')
yline(-H,':')
% animation settings and time steps
fps = 25
nframes = round(tEnd*fps)
tList = linspace(0,tEnd,nframes);
% update the ball's position in a loop
for i = 1:length(tList)
t = tList(i);
h.ball.XData = xBall + dxfcn(t);
h.ball.YData = yBall + dyfcn(t);
drawnow
end

More Answers (0)

Community Treasure Hunt

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

Start Hunting!