2021-07-01

Angles From 3 Points

Animation example

Given these 3 points:

\[A = (20,60), B = (80,60), C = (70,20)\]

Create the following animation:

The segment \(\overline{AC}\) aligns with segment \(\overline{AB}\)...

\[ \begin{align} &\overrightarrow{AB} = B - A = (80-20,60-60) = (60,0)\\ &\overrightarrow{AC} = C - A = (70-20,20-60) = (50,-40) \end{align} \]

This creates 2 vectors. Let's call them \(\textbf{u}\) and \(\textbf{v}\):

\[ \begin{align} &\textbf{u} = \overrightarrow{AB} = (60,0)\\ &\textbf{v} = \overrightarrow{AC} = (50,-40) \end{align} \]

To produce the previous animation, we have to rotate the segment \(\overline{AC}\), in such a way that its direction matches the direction of the segment \(\overline{AB}\)...

That is, we need a rotation point and an angle of rotation for segment \(\overline{AC}\)...

In this case the rotation point is the point \(A\), and the angle of rotation is the inner angle between vectors \(\textbf{u}\) and \(\textbf{v}\):

The angle between vectors \(\textbf{u}\) and \(\textbf{v}\) can be derived from the formula of the dot product:

\[ \textbf{u} \cdot \textbf{v} = \|\textbf{u}\| \|\textbf{v}\| \text{cos} \measuredangle (\textbf{u},\textbf{v}) \]
\[ \begin{align} &\text{cos} \measuredangle (\textbf{u},\textbf{v}) = \frac{\textbf{u} \cdot \textbf{v}}{\|\textbf{u}\| \|\textbf{v}\|}\\\\ &\measuredangle (\textbf{u},\textbf{v}) = \text{arccos}\left(\frac{\textbf{u} \cdot \textbf{v}}{\|\textbf{u}\| \|\textbf{v}\|}\right) \end{align} \]

Which gives us:

\[ \begin{align} &\textbf{u} = (60,0)\\ &\textbf{v} = (50,-40)\\\\ &\measuredangle (\textbf{u},\textbf{v}) \approx 0.675 \text{ rad} \end{align} \]

We can express this angle in degrees if we need it:

\[ \begin{align} &\measuredangle (\textbf{u},\textbf{v}) \approx 0.675 \text{ rad}\\\\ &\theta = \measuredangle (\textbf{u},\textbf{v}) \times \frac{180}{\pi} \approx 38.66^{\circ} \end{align} \]

Now we can start animating. In my case, I use SVG.js:

var A = {x:20, y:60}
var B = {x:80, y:60}
var C = {x:70, y:20}

var theta = 38.66

var rotationPointX = A.x;
var rotationPointY = A.y;

var segmentAB = canvas.line([A,B]).attr({
    ...
})
var segmentAC = canvas.line([A,C]).attr({
    ...
})

segmentAC.animate(time).rotate(theta, rotationPointX, rotationPointY);
    

Watch the video: