analysis, find series, switch expression, event function, billiard game

1 view (last 30 days)
Ansgar Elles on 17 Feb 2021
Commented: Walter Roberson on 17 Feb 2021
Hi, im simulating the movement of balls on a pool table. I want the user to chose his desired number of balls (theoretically from 1 to inf).
Whenever a ball is colliding with the wall or another ball, an event function is triggered and the new parameters need to be calculated.
I want to use the output of the event function ,,ie" (which represents the index of the event, that has been triggered) to determine what happend (collision with wall/ball) and also to determine which ball is affected. The code must be universal, so that no matter the number of balls, the output ie is "translated" into the right input for a switch expression, which calculates the new parameters for the right ball
Until now my switch expression looks like that (for two balls):
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[t,y,te,ye,ie] = ode45(@kinematics,tspan,vals_balls,options);
if ie == [5,7] | ie == [1,7] | ie == [1,3] | ie == [5,3] %ball_1 into corner, isequal could be used too
ie = 1.1;
elseif ie == [6,8] | ie == [2,8] | ie == [2,4] | ie == [6,4] %ball_2 into corner
ie = 2.1;
end
switch ie
case {1,5} %ball_1 left/right border
vals_balls = [y(end,1), -y(end,2), y(end,3), y(end,4), y(end,5), y(end,6), y(end,7), y(end,8)];
case {2,6} %ball_2 left/right border
vals_balls = [y(end,1), y(end,2), y(end,3), y(end,4), y(end,5), -y(end,6), y(end,7), y(end,8)];
case {3,7} %ball_1 bottom/top border
vals_balls = [y(end,1), y(end,2), y(end,3), -y(end,4), y(end,5), y(end,6), y(end,7), y(end,8)];
case {4,8} %ball_2 bottom/top border
vals_balls = [y(end,1), y(end,2), y(end,3), y(end,4), y(end,5), y(end,6), y(end,7), -y(end,8)];
case 1.1 %ball_1 into corner
vals_balls = [y(end,1), -y(end,2), y(end,3), -y(end,4), y(end,5), y(end,6), y(end,7), y(end,8)];
case 2.1 %ball_2 into corner
vals_balls = [y(end,1), y(end,2), y(end,3), y(end,4), y(end,5), -y(end,6), y(end,7), -y(end,8)];
case 9 %balls colliding
connection = [y(end,5)-y(end,1), y(end,7)-y(end,3)];
v1_transferred = (y(end,2)*connection(1) + y(end,4)*connection(2))*connection/(norm(connection)^2);
v1_conserved = [y(end,2), y(end,4)] - v1_transferred;
v2_transferred = (y(end,6)*connection(1) + y(end,8)*connection(2))*connection/(norm(connection)^2);
v2_conserved = [y(end,6), y(end,8)] - v2_transferred;
vals_balls = [y(end,1), v1_conserved(1)+v2_transferred(1), y(end,3), v1_conserved(2)+v2_transferred(2), y(end,5), v2_conserved(1)+v1_transferred(1), y(end,7), v2_conserved(2)+v1_transferred(2)];
case 10 %balls not moving anymore
disp('Die Kugeln rollen nicht mehr.')
stillrolling = 0;
end
-------------------------------------------------------------------------------------------------------------------------
Dont bother with ie 1.1 and 2.1 these are "special" cases so to speak when the ball goes right into the corner. First it would be awesome to get to work the "basic" code.
So... now in order to make the right "choice" for the switch expression we need to translate "ie" (depending on the number(#) of balls) into a scalar for the case and into a
scalar for the ball affected (ball #). See this table.
Furthermore the following calculates the number of "ie"s. n is the number of balls. I dont know if this helps...:

Walter Roberson on 17 Feb 2021
if ie == [5,7] | ie == [1,7] | ie == [1,3] | ie == [5,3] %ball_1 into corner, isequal could be used too
ie == [5,7] is a vector test, equivalent to [ie == 5, ie == 7] for scalar ie or column vector ie (ie from ode45 will be a scalar or column vector.)
When you have a vector being tested in if or while then MATLAB considers the test to be true provided that all values being tested are non-zero, with false being 0 and true being 1. Thus, ie == [5,7] is true where ie equals 5, and is true where ie equals 7, and the two condtions are effectively "and"'d together. But there does not exist any value of ie which can simultaneously equal 5 and 7, so the and will fail. Therefore your series of tests will fail.
Perhaps you are expecting ie to contain multiple indices, corresponding to encountering multiple conditions simultaneously. However, the documentation for ie is clear that it is a column vector, not a row vector. If you were wanting to test that ie contains both 5 and 7 then you would need to be careful about the fact you would be comparing a column vector to a row vector.
Walter Roberson on 17 Feb 2021
you did not ask a question. You said what you want to do and posted some code and I pointed out why the code would not work. Wasn't that the question implied, "Why doesn't my code decode the event properly?"