25

I apologize if this is put inelegantly as I'm new to this type of mathematics, but I thought of this experiment and can't stop turning it over in my mind.

Take any set of points on a 2d plane and connect every point to every other point using line segments. Now take the midpoints of each of those lines and remove the original points and line segments, then repeat the process of connecting and finding the midpoints with this new set of points and so on.

For any set of points that all lie on the same line it is trivial as after enough repetitions of this process it will eventually reduce to just one point. For any set of 3 points it is also trivial, as the points will either lie on the same line or form a triangle, and all triangles fall into a pattern of creating a smaller and inverted triangle.

However sets of 4 or more points quickly become very complex. Edit: a square starts with 4 points, after one step becomes 5 points (arranged in a square rotated 45 degrees with a point in it's center), then becomes 9 (arranged in a 3x3 grid rotated another 45 degrees), at which point it becomes too complicated for me to continue by hand. I've been using GeoGebra to model this but it's tedious to do and as I said becomes complicated.

What I would like to know is if there is a way to take a set of points and describe how it will "evolve" as it goes through this process. Additionally I would like to know if there is if there is some software that is better suited to this task?

Ananke
  • 353
  • 4
    The 1d analysis is wrong. I.e. if you have 6 points then the midpoints from just the first three will converge to a point and the midpoints of the last 3 will converge to a different point, so in the limit, it doesn’t converge to a single point. Rather, I think it converges to some dense subset of an interval. – Eric Feb 20 '25 at 19:11
  • @Pranay Yes sorry I meant a square, I have edited the post to reflect this – Ananke Feb 20 '25 at 19:14
  • @Eric Thank you, I forgot to consider that points not next to each other are still connected and will produce another point. – Ananke Feb 20 '25 at 19:29
  • @Ananke If a midpoint between two points at iteration $t$ was also a point at iteration $t$, do we remove it when constructing iteration $t+1$? I assume so because of your square example (if not, then the center of the square would be missing from the third iteration), but I wanted to check that this is intended. – Carl Schildkraut Feb 21 '25 at 06:34
  • 3
    @Eric This is a good general principle, actually - if the set contains three points whose barycentre is X, then all future iterations will contain three points whose barycentre is that same X. Mark all the barycentres of three points, and you know the shape will never get smaller than that. – Toph Feb 21 '25 at 16:17
  • By the way, I've asked a follow-up question here about the shape that the square converges to. – Varun Vejalla Mar 02 '25 at 18:18

1 Answers1

18

Nice question! This is not a complete answer. For a square it's not so bad. It's easier to do the next iteration after the $9$ points by hand, I think. After that, here's a plot of what happens produced by a Python script written by GPT-4o:

midpoint iteration

These plots clearly suggest the following, which are not hard to prove by induction:

  1. If the initial points have coordinates $(0, 0), (1, 0), (0, 1), (1, 1)$, then after the $n^{th}$ iteration all points have coordinates with denominators $\frac{1}{2^n}$.

  2. Moreover, at every iteration the points consist of a "boundary" of some points in the lattice $\frac{1}{2^n} \mathbb{Z}^2$, together with all lattice points inside their convex hull.

  3. To compute the next iteration from the previous one we can restrict our attention to drawing line segments between adjacent points in the lattice (including diagonally adjacent), together with all points from the previous iteration except the extreme points.

So it remains to understand the behavior of the boundary. Visually this is clearly converging to a circle (Edit: just kidding, see the comments!); I think the intuitive idea is pretty clear here, repeatedly taking midpoints is smoothing out all the corners. I'm not sure what the cleanest way to actually prove this is, though. I'm also not sure whether the radius converges to a positive constant or to zero. It looks like it might be... $\frac{1}{4}$?

In the general case it seems that a given starting configuration of points converges fairly rapidly to a specific convex set; note that in general if there are $n$ points in a given iteration then the next iteration could have as many as ${n \choose 2}$ points which is really quite a lot so it's hard to be more precise than this. I will stick to points lying on a lattice to keep things manageable. Here's what happens when we start with one additional point added to the square, a midpoint of one side:

5 point midpoints

I don't even have a guess about what that limiting shape is. Note that it's flat on the bottom and has a corner at the top, so I was wrong about taking midpoints always smoothing out corners!

Here's what happens when we replace a corner with two side midpoints:

weird little bean

Here's what happens when we move one of those side midpoints up (not pictured in the first iteration but you can see it's still affecting future ones):

another little bean

In case the link breaks, here's the Python script:

import numpy as np
import matplotlib.pyplot as plt
from itertools import combinations

def compute_midpoints(S): """Compute the set of midpoints between all distinct pairs in S.""" return {(0.5 * (p1[0] + p2[0]), 0.5 * (p1[1] + p2[1])) for p1, p2 in combinations(S, 2)}

def get_initial_points(): """Return a default set of initial points. Modify this manually if needed.""" return {(0, 2), (1, 0), (-1, 1), (1, -1), (-1, -1)}

def generate_sequence(n, S1): """Generate the sequence S_1, ..., S_n iteratively with custom S1.""" S = [S1] for _ in range(n - 1): S.append(compute_midpoints(S[-1])) # Only midpoints are included return S

def plot_sequence(S): """Plot each set S_n separately.""" num_plots = len(S) fig, axes = plt.subplots(2, (num_plots + 1) // 2, figsize=((num_plots + 1) // 2 * 6, 12)) # Split into 2 rows axes = axes.flatten()

for i, (ax, points) in enumerate(zip(axes, S)):
    points = np.array(list(points))
    ax.scatter(points[:, 0], points[:, 1], c='b', s=40)  # Increased point size
    ax.set_title(f"S_{i+1}")
    ax.set_xlim(-1.5, 1.5)
    ax.set_ylim(-1.5, 1.5)
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_aspect('equal')

# Hide unused subplots if any
for j in range(i + 1, len(axes)):
    fig.delaxes(axes[j])

plt.tight_layout()
plt.show()

Get custom initial points

S1 = get_initial_points()

Generate and plot the sequence up to S_8

S_sequence = generate_sequence(8, S1) plot_sequence(S_sequence)

Qiaochu Yuan
  • 468,795
  • 2
    Every point in the $n$th iteration has the form $\sum_{x \in X} \alpha_x \cdot x$ with $\alpha_x \in \frac{1}{2^n} \mathbb{Z}$ for $x \in X$ and $\sum_{x \in X} \alpha_x = 1$. I'm not so good with Python, but maybe looking which functions $\alpha \in [0, 1]^X$ are possible, and which probability distributions on $X$ they can converge to, would give more useful info? – Adayah Feb 21 '25 at 10:59
  • @Adayah: the script does not keep track of duplicate points to reduce the amount of computation but seeing the distribution would be interesting, yes. I suppose you could keep track of multiplicities instead of keeping track of separate points. – Qiaochu Yuan Feb 21 '25 at 14:10
  • I mean the distributions on $X$ given by each point of the $n$th iteration (name it $X_n$), not the one distribution on $X_n$ arising from multiple pairs producing the same point. When $\mu_y$ is such a distribution coming from some $y \in X_n$, then $y = \int_X x , \text{d} \mu_y(x) =: \varphi(\mu_y)$. The limiting set would then be $${ \varphi(\mu) : \mu \text{ is a limit of possible distributions} }.$$ – Adayah Feb 21 '25 at 14:54
  • 6
    Nice diagrams! I wanted to point out that the limiting object from a square can't be a circle: the furthest points in the "up-right" direction of the sixth iteration are the four points $$\left(\frac{23}{32},\frac{20}{32}\right),\left(\frac{22}{32},\frac{21}{32}\right),\left(\frac{21}{32},\frac{22}{32}\right),\left(\frac{20}{32},\frac{23}{32}\right).$$ These four points alone give that the segment connecting $(22/32,21/32)$ and $(21/32,22/32)$ is contained in the limiting shape, and no point $(x,y)$ with $x+y>43/32$ can be in the limit. So the limiting shape contains a segment on its boundary. – Carl Schildkraut Feb 21 '25 at 18:33
  • @Carl: huh, thanks! That's what I get for not zooming in far enough, I guess. – Qiaochu Yuan Feb 21 '25 at 19:42
  • 1
    If one moves to coordinates where we start with pm1, pm1, then Carl's points are (7 4, 6 5, 5 6, 4 7)/16, and line x+y=11/16. At iteration 7 there is a support line through (13 9, 14 7, 15 5) and 2x+y = 35/32 is the support of all later stages at that slope. This stabilization happens for all rational slopes. – Max Feb 22 '25 at 15:50
  • @QiaochuYuan maybe you can ask the ai to compute support lines/square distances to border at rational slopes, and then suggest the shape or its polar dual. – Max Feb 22 '25 at 16:10
  • This process and the resulting shapes strongly remind me of Bezier curves, even more so when there are so many rational points in the boundary (as computed by @CarlSchildkraut and @Max) – Jacopo G. Chen Feb 25 '25 at 16:43
  • @Max Do you have a proof that this happens for all rational slopes? It would also be interesting to know whether one can classify for which rational slopes one has a segment (like slope $\pm 1$) or only a single point (like slope $0$ or $\infty$). – Carl Schildkraut Feb 25 '25 at 21:14
  • 1
    For the square, if you write the starting points as $(\pm1, \pm1)$, the set of points is a subset of $\frac{1}{2^{k}}{(x,y)\mid x^2+y^2\le 2^{2k-2}+2\wedge (x,y)\in\mathbb{Z}^2}$, at least for the first eight iterations. And it is exactly equal (i.e. not just a subset) for the first six iterations. – Varun Vejalla Feb 27 '25 at 08:16
  • @Varun: that's very nice! If you have more details that you'd like to write up in another answer I think that would be valuable. – Qiaochu Yuan Feb 27 '25 at 16:02