Web toy: the Gauss-Lucas theorem

The Gauss-Lucas theorem says that given any polynomial $P$ in the complex numbers, the roots of the derivative $P'$ are contained in the convex hull of the roots of $P$ itself.

The proof is short and simple enough to reproduce here. WLOG let $P$ be monic (leading coefficient of 1), so that we can write it as $P(z)=\prod_i(z-r_i)$, where $(r_i)$ are the roots of $P$. Then the product rule gives us $$P'(z) = \sum_i \left( \prod_{j\neq i} (z-r_j) \right) = \sum_i \frac{P(z)}{z-r_i}$$

Now let $z$ be a root of $P'$. If it is a root of $P$ as well, then the theorem is already satisfied; so we may assume $P(z)\neq 0$. Then we have $$0 = \frac{P'(z)}{P(z)} = \sum_i \frac{1}{z-r_i} = \sum_i \frac{\overline{z}-\overline{r_i}}{|z-r_i|^2} = \overline{z} \sum_i \frac{1}{|z-r_i|^2} - \sum_i \frac{\overline{r_i}}{|z-r_i|^2}$$

For convenience, write $w_i=1/|z-r_i|^2$, and $W=\sum_i w_i$. Then the above equation becomes $\overline{z}W = \sum_i \overline{r_i} w_i$. Taking the complex conjugate and rearranging, we get $z=\sum_i r_i (w_i/W)$. And since $(w_i)$ are positive real numbers, their scaled versions $(w_i/W)$ must be positive real numbers summing to 1, i.e. this is precisely saying that $z$ is a convex combination of $(r_i)$.

Here’s an HTML5 web toy that lets you play with this concept. The roots of $P$ are shown as filled circles, and the roots of $P'$ as empty circles. Drag any circle, and the roots of the other polynomial will update automatically to match. The current convex hull of the roots of $P$ is shown as a polygon connecting the appropriate subset of the filled circles.

Middle-click or Shift-click in an empty area to create an extra root of $P$; middle-click or Shift-click on an existing point (either a root of $P$ or one of $P'$) to remove it.

If you drag a filled circle, there is only one possible thing that can happen (because the roots of $P$ uniquely determine $P$ itself, which in turn uniquely determines $P'$ and its roots). But if you drag an empty circle, there isn’t quite such a well defined answer, because $P'$ only determines $P$ up to the constant of integration. The program has to make an arbitrary choice to resolve this ambiguity: it chooses to update $P$ so as to keep its constant term the same (and also constraining it to remain monic) while a root of $P'$ is being moved.

To make it easy to adjust the constant term after that operation, you can also Ctrl-drag a filled circle, which will move that root of $P$ by means of only changing the constant term, so that the roots of $P'$ will stay fixed and all the other roots of $P$ will move instead.

(Tested on Firefox only, so far. Requires SVG and Javascript. Also, this is a toy – it's written in a really simple way, so numerical stability issues are to be expected.)