So we are asked to create a program that simulates cue balls hitting eachother, combined from various sniplets of coding, compiled in MatLabs. Now I am asked to introduce the element of friction to the table. So the balls must lose speed over time if they are moving, bringing them to a halt. I thought about doing it like this:
If speed > 0 then set speed = speed - speed*0.90
At first I wanted to just say speed = speed * 0.90 but this would never bring the balls to a complete stop, so I figured I need a logiccase to see if they are moving (Maybe I need a 2nd if inside, saying if speed <0 then set speed = 0, to stop the ball if the speed is now below zero?) Anyway here is the code, I am not sure how the coding of MatLab works, I tried copypasting syntax but i keep getting a prgoram crash.
% Program Desc.: The program will create a virtual simulation of cue balls on a pool table.clearall;clf;% Resets parameters% [Region] Define global variablestable=[2.54,1.27];% Size of virtual table [meters]dt=0.01;% Time interval between calculations [seconds]time=10;% Time to run simulation [seconds]% [Region] Define global variables% [Region] Initial ball parametersballs(1).pos=[0.4,0.6];% Ball no. 1 initial transform from bottom-left [meters]balls(1).v=[0,0];% Ball no. 1 initital velocity [m/s]balls(1).r=0.05;% Ball no. 1 initial radius for impact calculations [meters]balls(1).color='green';% Ball no. 1 initial color.balls(2).pos=[table(1)-0.40.6];% Ball no. 2 initial transform from bottom-left [meters]balls(2).v=[0,0];% Ball no. 2 initital velocity [m/s]balls(2).r=0.05;% Ball no. 2 initial radius for impact calculations [meters]balls(2).color='red';% Ball no. 2 initial color.balls(3).pos=[0.25,1];% Ball no. 3 initial transform from bottom-left [meters]balls(3).v=[6,-1.8];% Ball no. 3 initital velocity [m/s]balls(3).r=0.05;% Ball no. 3 initial radius for impact calculations [meters]balls(3).color='blue';% Ball no. 3 initial color.% [Region] Initial ball parametersfort=0:dt:timefora=1:length(balls)% [Region] Update position% balls(a).pos = balls(a).pos + balls(a).v .* dt; % Update transform from old transform + current speed * passed time interval.balls(a).pos=balls(a).pos+balls(a).v.*dt;NEWCODEHERE?????
% [Region] Update position% [Region] Check for collision with wallifballs(a).pos(1)-balls(a).r<=0... % Compare (1) coordinate of transform to radius of current transform.||balls(a).pos(1)+balls(a).r>=table(1)% Compare (1) coordinate of transform to table variables (1) coordinate.balls(a).v(1)=-balls(a).v(1);% If True: Change velocity to reverse direction for (1) coordinate.endifballs(a).pos(2)-balls(a).r<=0... % Compare (2) coordinate of transform to radius of current transform.||balls(a).pos(2)+balls(a).r>=table(2)% Compare (2) coordinate of transform to table variables (2) coordinate.balls(a).v(2)=-balls(a).v(2);% If True: Change velocity to reverse direction for (2) coordinate.end% [Region] Check for collision with wall% [Region] Check for collision with ballsforb=a+1:length(balls)ifnorm(balls(b).pos-balls(a).pos)<=balls(b).r+balls(a).r% Calculate unit normalun=(balls(b).pos-balls(a).pos)./norm(balls(b).pos-balls(a).pos);ut=[-un(2),un(1)];% Unit tangent% Project velocity vectors into (normal,tangent)-coordinatsv_an=dot(un,balls(a).v);v_at=dot(ut,balls(a).v);v_bn=dot(un,balls(b).v);v_bt=dot(ut,balls(b).v);% Find velocities after collisionv_anp=v_bn.*un;v_atp=v_at.*ut;v_bnp=v_an.*un;v_btp=v_bt.*ut;% Add up the components for the resulting velocityballs(a).v=v_anp+v_atp;balls(b).v=v_bnp+v_btp;endend% [Region] Check for collision with ballsendshow(table,balls)pause(dt)end
That's not the appropriate way to simulate friction. Friction is subtractive, not multiplicative.
You want to remove a certain amount of velocity per second from the portion of the ball's velocity that is parallel to the surface, based upon the coefficient of friction between the balls and the table, and multiplied by the force of gravity.
Since you (presumably) don't have to worry about slopes or changes in gravity, you should simply subtract a (very small) amount of velocity from each ball each frame, multiplied by the reciprocal of the number of animation frames per second.
For example:
(new velocity this frame) = (currrent velocity) - (friction constant) * (1 / 30 updates per second = 0.0333...)
Of course, this is obvious, but you need to check that this doesn't bring the balls to negative velocity and set the velocity to 0 if it does.
Your solution depends on if you want to make an accurate math/physical simulation or if you want to make a game. If you are into making a game, you can always do all sorts of shortcuts to make it work. Making games engineering (make it work) while physics simulation is more scientific and detailed. Of course, the two are related, but the difference in solution depends on the end goal.
Your solution depends on if you want to make an accurate math/physical simulation or if you want to make a game. If you are into making a game, you can always do all sorts of shortcuts to make it work. Making games engineering (make it work) while physics simulation is more scientific and detailed. Of course, the two are related, but the difference in solution depends on the end goal.
No, that's not correct in this situation. There is no other way to mathematically model decent looking friction. Anything else would just be wrong. Besides, the formula I posted couldn't be any simpler.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
Hi Forum!
So we are asked to create a program that simulates cue balls hitting eachother, combined from various sniplets of coding, compiled in MatLabs. Now I am asked to introduce the element of friction to the table. So the balls must lose speed over time if they are moving, bringing them to a halt. I thought about doing it like this:
If speed > 0 then set speed = speed - speed*0.90
At first I wanted to just say speed = speed * 0.90 but this would never bring the balls to a complete stop, so I figured I need a logiccase to see if they are moving (Maybe I need a 2nd if inside, saying if speed <0 then set speed = 0, to stop the ball if the speed is now below zero?) Anyway here is the code, I am not sure how the coding of MatLab works, I tried copypasting syntax but i keep getting a prgoram crash.
@Deeweext: Go
That's not the appropriate way to simulate friction. Friction is subtractive, not multiplicative.
You want to remove a certain amount of velocity per second from the portion of the ball's velocity that is parallel to the surface, based upon the coefficient of friction between the balls and the table, and multiplied by the force of gravity.
Since you (presumably) don't have to worry about slopes or changes in gravity, you should simply subtract a (very small) amount of velocity from each ball each frame, multiplied by the reciprocal of the number of animation frames per second.
For example: (new velocity this frame) = (currrent velocity) - (friction constant) * (1 / 30 updates per second = 0.0333...)
Of course, this is obvious, but you need to check that this doesn't bring the balls to negative velocity and set the velocity to 0 if it does.
@grim001: Go
Your solution depends on if you want to make an accurate math/physical simulation or if you want to make a game. If you are into making a game, you can always do all sorts of shortcuts to make it work. Making games engineering (make it work) while physics simulation is more scientific and detailed. Of course, the two are related, but the difference in solution depends on the end goal.
No, that's not correct in this situation. There is no other way to mathematically model decent looking friction. Anything else would just be wrong. Besides, the formula I posted couldn't be any simpler.