# Simulate a polygon bouncing with collision detection inside a circle/polygon.

the example can be see in help page by searching WhenEvent;

ball2d[r_?NumericQ] := Reap@NDSolveValue[{{x'[t] == vx[t], y'[t] == vy[t], x1'[t] == vx[t],

y1'[t] == vy[t]}, WhenEvent[{x[t]^2 + y[t]^2 == 1,   x1[t]^2 + y1[t]^2 == .9}, {x1[t] ->

x[t] + (pp = RandomReal[.1]),   y1[t] -> y[t] + Sqrt[0.02 - pp^2], vy[t] -> -.9 vy[t],

vx[t] -> -.9 vx[t]}],x[0] == 0, y[0] == 0, x1[0] == .1, y1[0] == .1, vx[0] == 1,

vy[0] == 1}, {x[t], y[t], x1[t], y1[t]}, {t, 0, 200},DiscreteVariables -> {vx, vy}];

{sol1, v} = ball2d[4/3];

Manipulate[ ParametricPlot[#, {t, 0, [Tau]}, Frame -> True, PlotRange -> 2,

PlotPoints -> 10, PlotStyle -> Thickness[0.02],Epilog -> {PointSize[.05], Point[# /. (t -> [Tau])],

ContourPlot[{x^2 + y^2 == 1}, {x, -1, 1}, {y, -1, 1}][[1]]}] & /@

Partition[sol1, 2], {{[Tau], 11.9}, 0.01, 198},  SaveDefinitions -> True]


The following example show a stick bouncing inside a circle, not so good

What's the right way?

How can I go forward to replace the stick with a triangle or a polygon? and futher a polygon3d?

Any examples?

Manipulate[ ParametricPlot[#, {t, 0, [Tau]}, Frame -> True, PlotRange -> 2,

PlotPoints -> 10, PlotStyle -> Thickness[0.0001],Epilog -> {Pink, Thick,

Line[{{#[[1]], #[[2]]}, {#[[3]], #[[4]]}}] /. (t -> [Tau]),  ContourPlot[{x^2 + y^2 == 1}, {x, -1, 1}, {y, -1, 1}][[1]]}] &@

sol1, {{[Tau], 0.01}, 0.01, 198, .1}, SaveDefinitions -> True]


The reference posted by Mr.Wizard is about a point model which is much simpler. My question is about extending the example in WhenEvent help page. However the animation is really shown by that example, can you image a stick bouncing like that?

• Related: (38927) Commented Feb 8, 2015 at 7:40
• @Mr.Wizard not duplicate, Disk is point model, polygon or stick in rigid model with more freedom. Commented Feb 13, 2015 at 1:53
• Question reopened. Personally I would find additional differentiation from the previous question beneficial, even if it seems like stating the obvious to you. Commented Feb 13, 2015 at 10:24

The keypoint is the equation and the events. The example in a rotation line, the keypoint is to express endpoints of a line.

p = 1;
ball2d[r_?NumericQ] := Reap@NDSolveValue[{
x'[t] == vx[t],
WhenEvent[{Abs[(x[t] + 0.1*Cos[p*t])] - 1 >= 0,
Abs[(x[t] - 0.1*Cos[p*t])] - 1 >= 0},
If[x[t] >= 0, vx[t] -> -Abs@vx[t], vx[t] -> Abs@vx[t]]
],
y'[t] == vy[t],
WhenEvent[{Abs[(y[t] + 0.1*Sin[p*t])] - 1 >= 0,
Abs[(y[t] - 0.1*Sin[p*t])] - 1 >= 0},
If[y[t] >= 0, vy[t] -> -Abs@vy[t], vy[t] -> Abs@vy[t]]
],
x[0] == 0, y[0] == 0.3, vx[0] == 0.1 + RandomReal[0.1],
vy[0] == 0.1 + RandomReal[0.1]
}, {x[t], y[t], vx[t], vy[t]}, {t, 0, 200, .01},
DiscreteVariables -> {vx, vy}];
{sol1, flag} = ball2d[.01]
g = Manipulate[
ParametricPlot[#, {t, 0, \[Tau]}, Frame -> True, FrameTicks -> None,
PlotRange -> 1, Axes -> True, PlotPoints -> 500,
PlotStyle -> Thickness[0.000],
Epilog -> {RegionPlot[{-1 < x < 1, -1 < y < 1}, {x, -1,
1}, {y, -1, 1}][[1]], PointSize[.01],
Point[# /. (t -> \[Tau])],
Line[{# - 0.1 {Cos[t], Sin[t]}, # +
0.1 {Cos[t], Sin[t]}} /. (t -> \[Tau])]}] &@
sol1[[1 ;; 2]], {{\[Tau], 5.9}, 0.01, 200, .01},
SaveDefinitions -> True]


Debug

endpoint1[x_,y_,q_]:={x+0.1*Cos[q],y+0.1*Sin[q]}
endpoint2[x_,y_,q_]:={x-0.1*Cos[q],y-0.1*Sin[q]}
debug[t0_]:=Block[{},
x1=sol1[[1]]/.t->t0;
y1=sol1[[2]]/.t->t0;
vx1=sol1[[3]]/.t->t0;
vy1=sol1[[4]]/.t->t0;
{x1, y1, vx1, vy1, endpoint1[x1,y1,t0], endpoint2[x1,y1,t0]}
]


There is a problem, when vy[0]=0.05[a little small], event check will fail in some values. One can use my raw debug method to see. For example, when vy[61.1] is not set to be -0.01.

debug[60.8]
{-0.52062,0.908,-0.1,0.01,{-0.565109,0.818442},{-0.47613,0.997558}}
debug[61.1]
{-0.55062,0.911,-0.1,0.01,{-0.566656,0.812294},{-0.534583,1.00971}}