[Math] Coordinate of intersection between line and square

geometryparametrictrigonometry

TL;DR given a square and a point $p$, I need the intersection between the perimeter of the square and a ray cast from the center of the square through point $p$. This is my approach so far, but I will also accept correct answers that use a totally different approach.

I’m writing an iPad app where there is a square on the screen. The user drags their finger around the screen. Imagine an ray starting at the center of the square and passing through the point where their finger is touching. I need to do stuff on the screen at the intersection between that line and the center of the square.

The way I am doing this currently is by using the parametric equation of a square that I found at this answer:

$$\begin{align*}x&=p\left(|\cos\,t|\cos\,t+|\sin\,t|\sin\,t\right)\\y&=q\left(|\cos\,t|\cos\,t-|\sin\,t|\sin\,t\right)\end{align*}$$

And for $t$, I am using the angle of the ray formed by the person’s finger. I am placing a small dot at the point given by that equation, just so I can see what I’m working with. I have to multiply that angle by $-1$ and add $\pi\over4$ so that the angles match up.

My problem is that the equation of a square does not vary at the same rate as the angle. For any given value of $t$, a ray cast from the center of the square to the user’s finger does not pass through the square at the point given by the above equation, except at the centers of the sides and at the exact corners. The effect is that the dot I am putting on the screen lags or ahead of the user’s finger.

Is there any way to get the point returned by the above equation to be collinear with the line from the center to the user’s finger?

Here’s an illustration I put together in the OS X Grapher application so you can see what I mean. If you have a Mac, you can also download the file and play with it yourself.

Illustration of the problem.

Best Answer

Here's an answer:

u = max(|x|, |y|);

xp = x / u;
yp = y / u;

return (xp, yp);

You can see that this produces a point one of whose coordinates is either $+1$ or $-1$; it's a scalar multiple of $(x, y)$, so it lies on the line from $(0,0)$ through $(x, y)$. And because the multiplier ($1/u$) used is positive, it lies on the same side of $(0,0)$ as $(x,y)$ does.

Note that if both $x$ and $y$ are zero, the procedure fails...but that's to be expected.

Related Question