The animation

My brother asked for my help to build an animation of a trapezoid inscribed in a circle that kept changing his shape. With a bit of maths and the help of ChatGPT for the UI, I created the animation you can see below. Under the animation you can find a control panel that allows you to tweak some animation parameters, and under that you can find a brief explanation of how the animation works.

Cyclic trapezoid controls
Colour
Point A
Point B
Point D
Global
Point C is computed from the cyclic trapezoid rule: angleC = alpha + angleB + angleD.

How it works

The first thing I determined was that one of the points might as well move at a constant speed around the circle, to induce some movement, but without being too crazy. Can you look at the animation and figure out which of the four points is the one that moves around at a constant speed?

It's point \(A\).

Since the trapezoid \(ABCD\) was supposed to be inscribed in a circle of centre \(O = (0, 0)\), I thought it was probably a good idea to define the position of point \(A\) in terms of the angle \(\alpha\) that the radius \(OA\) makes with the radius that goes through \(P\), if \(P\) is the point \((1, 0)\).

After a bit of back and forth, and some doodling, I ended up defining the positions of \(B\) and \(D\) in terms of the angles that \(OB\) and \(OD\) make with \(OA\). This means that animating the points \(B\) and \(D\) is a matter of animating those angles. Animating the angles is better than animating the positions of the points because it's easier to parametrise a single angle than it is to parametrise two coordinates.

The angle that defines points \(B\) and \(D\), with respect to \(\alpha\), is given by a function of the form

\[ \frac{\theta_{m} + \theta_{M}}{2} + \left(\theta_{M} - \theta_{m}\right) \cos\left(\frac{2\pi t}{\rho} + \phi\right)\]

  • \(t\) is the time elapsed during the animation;
  • \(\theta_{m}\) and \(\theta_{M}\) are the minimum and maximum attainable angles, respectively;
  • \(\rho\) is the period of the animation of the angles; and
  • \(\phi\) is the phase of the animation.

If points \(B\) and \(D\) have the exact same values for all four parameters, the animation doesn't look any fun. To create a sense of pleasing chaos, you want the periods and the phases for points \(B\) and \(D\) to be different, even if the minimum and maximum angles are the same.

So, two different functions produce two angles \(\Delta_{B}\) and \(\Delta_{D}\) and the positions of \(B\) and \(D\) are given by \(\alpha + \Delta_{B}\) and \(\alpha - \Delta_{D}\), respectively.

Once you have points \(A\), \(B\), and \(D\), the position of point \(C\) is completely determined. Instead of having to do some annoying calculations with positions and parallel lines, you can leverage the fact that the cyclic trapezoid has supplementary opposite angles to conclude that the position of point \(C\) is given by the angle \(\alpha + \Delta_{B} + \Delta_{D}\).

Become the smartest Python 🐍 developer in the room πŸš€

Every Monday, you'll get a Python deep dive that unpacks a topic with analogies, diagrams, and code examples so you can write clearer, faster, and more idiomatic code.

Previous Post