# Collision between a point and a square

Suppose we have a point of time laws:

xP[t_] := 0.40 + 0.51 t;
yP[t_] := 0.41 + 0.42 t;


and a square with side:

L := 2.01


and with center and angle of rotation of hourly laws:

xC[t_] := 0.50 - 0.01 t;
yC[t_] := 0.50 + 0.01 t;
θ[t_] := 0.52 + 0.01 t;


Defining the square as follows:

q = ImplicitRegion[Max[Abs[x - xC[t] + Tan[θ[t]] y],
Abs[y - yC[t] - Tan[θ[t]] x]] == L/2, {x, y}];


at time t = 0 the situation is as follows:

Show[Graphics[{PointSize[Large], Red, Point[{xP[0], yP[0]}]}],
RegionPlot[DiscretizeRegion[q /. {t -> 0}]],
PlotRange -> {{-2, 2}, {-2, 2}}]


Finally, to calculate the time t*>0 of the first collision between the point and the square I thought of solving the following equation:

NSolve[Max[Abs[xP[t] - xC[t] + Tan[θ[t]] yP[t]],
Abs[yP[t] - yC[t] - Tan[θ[t]] xP[t]]] == L/2 , t]


Unfortunately neither the plot nor the equation are successful and I do not know how to solve it.

Thank you!

• FindRoot[Max[Abs[xP[t] - xC[t] + Tan[[Theta][t]] yP[t]], Abs[yP[t] - yC[t] - Tan[[Theta][t]] xP[t]]] == L/2, {t, 1}] – jiaoeyushushu Sep 24 '17 at 9:28

Here is a function which you pass it the time, and will return True is point is inside the rectangle else False. This is based on test given in how-to-check-if-a-point-is-inside-a-rectangle

The implementation of the above is also given in finding-whether-a-point-lies-inside-a-rectangle-or-not which I translated to Mathematica and added a small Manipulate on top of it.

You call the function as follows

isPointInside[1.73]
(* true*)
isPointInside[1.74]
(* False*)


So point hits the edge between the above two values. Now that you have this function, you can easily find the exact t it changes from True to False.

Code:

xP[t_] := 0.40 + 0.51 t;
yP[t_] := 0.41 + 0.42 t;
xC[t_] := 0.50 - 0.01 t;
yC[t_] := 0.50 + 0.01 t;
L0 = 2.01;
angle[t_] := 0.52 + 0.01 t;

isPointInside[t_] :=
Module[{p1x, p1y, p2x, p2y, p4x, p4y, p21, p41, p, p21Mag, p41Mag},
{p1x, p1y} =
RotationTransform[angle[t], {xC[t], yC[t]}][{xC[t] - L0/2,
yC[t] + L0/2}];
{p2x, p2y} =
RotationTransform[angle[t], {xC[t], yC[t]}][{xC[t] + L0/2,
yC[t] + L0/2}];
{p4x, p4y} =
RotationTransform[angle[t], {xC[t], yC[t]}][{xC[t] - L0/2,
yC[t] - L0/2}];

p21 = {p2x - p1x, p2y - p1y};
p41 = {p4x - p1x, p4y - p1y};
p = {xP[t] - p1x, yP[t] - p1y};

p21Mag = Norm[p21]^2;
p41Mag = Norm[p41]^2;

If[0 <= p.p21 <= p21Mag && 0 <= p.p41 <= p41Mag,
True,
False
]
];

Manipulate[
tick;
Grid[{{Row[{txt, " at time = ", t}]},
{
Graphics[
{
{Blue, PointSize[.03], Point[{xP[t], yP[t]}]},
{Opacity[.1], EdgeForm[Thick], White,
Rotate[
Rectangle[{xC[t] - L0/2, yC[t] - L0/2}, {xC[t] + L0/2,
yC[t] + L0/2}], angle[t]]}
}
,
PlotRange -> {{-3, 3}, {-3, 3}}, Axes -> True, ImageSize -> 400]
}}],

Row[{Manipulator[Dynamic[t, {t = #;
If[ isPointInside[t],
txt = "Inside";
tick = Not[tick]
,
txt = "COLLISION !!"
]} &], {0, 4, .001}], Dynamic[t]}],
{{tick, False}, None},
{{txt, "inside"}, None},
TrackedSymbols :> {tick}
]


This is another simulation using faster rotation

• WoW, thanks a lot, it's all right! – TeM Sep 24 '17 at 14:24
• Why not use dot products + short-circuit evaluation? 0 <= p.p21 <= p21Mag && 0 <= p.p41 <= p41Mag – J. M.'s ennui Sep 24 '17 at 19:47
• @J.M. thanks for suggestion. As I said in the question, I just translated the small code shown in finding-whether-a-point-lies-inside-a-rectangle-or-not and was not trying to change it at time as it was working. But I just edited it to use the dot. – Nasser Sep 24 '17 at 20:10