The (7,2), (1,4) solution is surprisingly good. I did a really dumb brute force search and you have to get a decent ways out before you get anything better. Here are pairs of points for which there are no other better pairs with a lower max coordinate:
At first this was pretty surprising to me, and I was pretty sure it must be a bug in the code. Well, I tried it myself and got the same results. :-)
After a few false starts, here's what I think is the probable explanation. Note that we're trying to approximate √3 by a fraction of the form (ad-bc)/(ac+bd). The closest fractions we get (among a, b, c, d below a given magnitude) could be either below or above √3.
Consider an angle of (π/3+ε). If you look tan(π/3+ε)-tan(π/3), it works out to be (tan(ε) + 3ε) / (1 - ε√3).
When ε is replaced by -ε, if you look at tan(π/3)-tan(π/3-ε), it works out to be (tan(ε) + 3ε) / (1 + ε√3).
For small ε, the former, namely (tan(ε) + 3ε) / (1 - ε√3), is larger than the latter, namely (tan(ε) + 3ε) / (1 + ε√3). (More generally, this boils down to the fact that the second derivative of tan(x) is positive.)
This means that it's easier (you're allowed a larger difference in the angle) to achieve a given closeness of the fraction (ad-bc)/(ac+bd) to √3 by picking the angle to be greater than π/3 (=60°) than if the angle is less than π/3.
For larger denominators, √3 becomes about as easy to approximate to a given closeness from below as from above (by fractions of the form (ad-bc)/(ac+bd)), but among roughly equally distant approximations, the ones from above are closer in angle than the ones from below.
Can't edit the above post, but when trying to write this up more carefully I realized it's not correct:
(1) For one thing, the difference in epsilon is very small: the ratio (1 + ε√3)/(1 - ε√3) is 1+2√3ε+O(ε²), that is, we're comparing something like 4ε+4√3ε² versus 4ε-4√3ε², which is probably too small to matter.
(2) The argument looks like it applies to all angles, but in fact experimentation shows the same phenomenon does not appear, and finally,
Is it something special about 60 degrees, that causes this?
And could you elaborate? For example, take (11, 5) and (1, 10), which make an angle of roughly 59.845 degrees. Subtracting the smaller vector from the larger vector here gives (10, -5)… then what?
Yes, using some linear algebra:
- The inner product (or dot product) of two vectors is related to the angle (a,b) = |a||b|cos(angle).
- The cosine of 60 degrees is 1/2 (and it is increasing from 60 degrees to 0 degrees, where it is 1)
- The square Euclidean norm of the vector a-b is (a-b,a-b) = (a,a) - 2(a,b) + (b,b) = |a|^2 + |b|^2 - 2|a||b|cos(angle)
- Now let's |b| = x|a| for some x<1. Then the above becomes (1+x)|a|^2 - 2(x|a|^2)cos(angle)
- If cos(angle) > 1/2, then the result is less than |a|^2, which means that a-b is shorter than a
In your example, the angle between (10,-5) and (1,10) is approx 110 degrees, which means they are reduced with respect to each other and you cannot make them smaller.
Thanks. I guess what you've shown is that if two vectors a and b are at an angle such that cos(angle) > 1/2, then (a-b) is shorter than a. Don't we also need to say something about the angle between (a-b) and b? It's late at night and I can't figure out what that is. :-) I imagine we'd have to say that it's no further from 60° than the angle between a and b was (but actually that's not true, so I guess the claim is something else?)
Perhaps it would be easiest to understand with the example: we want to say that, though (11, 5) and (1, 10) make an angle very close to 60° (specifically, about 59.845°), there must exist a pair of vectors that make an angle even closer to 60°, and with smaller coordinates. What is this pair of vectors, and how do we arrive at it? (If one of them is their difference namely (10, -5), what is the other one?)
Also, I think the top-level comment here (by joefkelley) considered only vectors with positive coordinates (maybe?), so we may need to take that into account and/or explain why the coordinates are always positive.
Regarding the angle between (a-b) and b: you can repeat the process until you end up with two vectors that cannot be reduced with respect to one another. Eventually the angle will be between 60 and 120 degrees (because you can always negate a vector which turns an angle of x degrees into 180-x degrees). So this process of basis reduction does not make the angle closer to 60 necessarily, but merely puts the angle somewhere within the [60,120] range
When approximating 60 degrees from below, you will always be able to 'reduce' the length of the vectors (which likely reduces the individual coordinates due to the relation of the infinity norm and the Euclidian norm). This means you will need a different approach to the brute-force than taken in the top-level comment.
Only positive coordinates means that you are restricted to one of the quadrants. I suspect (but do not have time to figure out/prove right now, and it might not be true) that when your lattice contains vectors with optimal angle close to 60 degrees, that you can either rotate or otherwise find an isomorphic lattice that has only positive coordinates in its basis vectors. However, it may just be a side-effect of how the original list was produced.
You're still not addressing the main question: how do you prove that the closest approximation, among vectors of a given magnitude — whether you take this to be the infinity norm (max coordinate), the Euclidean norm, total length, whatever — will never approximate 60 degrees from below?
Yes, as you've said, when the angle between two vectors is less than 60 degrees, you can always “reduce” the length of the vectors, but what good is this reduction, if the angle actually gets farther away from 60 degrees? All it does is preserve the lattice, but that's not our goal here.
Thanks for explaining lattice basis reduction to me. Now I know more about it, which is great. I just don't see how it has any bearing on the question asked here (https://news.ycombinator.com/item?id=18538456): why is it that, when we enumerate the “best” solutions among those under a given magnitude, they always (after the first two) approximate 60° from above? Is it coincidence and does the pattern break down (will we see 59.999...x° eventually as an angle that cannot be beaten by smaller vectors), or is there a proof?
And if there is a proof, can you please illustrate with the example of (11, 5) and (1, 10), how to (procedurally) get a pair of vectors with smaller magnitude, but angle at least as close to 60° as in this pair? (Note that the lattice reduction step you gave takes the angle further away from 60°, so as far as I can tell it's not helpful.)
I suspect that the quality of the solution is due to the connection between continued fractions and best approximants. The author notes that the approximants alternate between being usable and non-usable, which is characteristic of continued-fraction-generated approximants, which "flip" every time and have a sort of parity as a result.
After constructing the two rays at an angle of approximately 60 degrees, the author goes about constructing an actual (approximate) equilateral triangle by drawing two perpendiculars. That might be useful if one needs a triangle of precisely that size, but given a pair of compasses (or a straightedge with two markings), one gets any ≈equilateral triangle by just marking the two intersection points of any circle around the origin with the two rays. I believe this method doesn't give anything less precise than the method outlined in the post.
Given that the idea was to make the construction simple and small, I'm surprised the compasses method wasn't chosen.
That's an interesting number set. The set of all points that can be produced from a straight-edge and the grid of integers.
I'm pretty sure this is just the grid of rational numbers. Interestingly, this is a subset of the 'constructible' numbers. That is, the numbers that can be produced from a compass and straight-edge (without even needing a grid).
It’s not so surprising, since once you have a compass, straightedge, and a line segment you call “unit length”, you can construct all of the integer valued points in the plane.
The post is titled “60-degree angles on a lattice”, and links to “how to draw a good approximation to an equilateral triangle on a piece of graph paper” — that is, the problem being considered is one where all coordinates have to be integers.
If you're willing to use compasses and get arbitrary coordinates, you don't need any of this, not even the first part — it's an entirely different (and much simpler) problem.
Oh, wow, beautiful. I wonder if there's a way to rephrase this as a diophantine approximation problem? If one ray must be axis-aligned then of course it's just the convergents for √3, but with two rays it's a little trickier.
We can indeed relate this problem to the “usual” Diophantine approximation problem of approximating a number α by a rational number p/q, but there's a twist.
The “usual” problem, where we want p/q to be close to a real number α, can be thought of as finding Gaussian integers (q + ip) that lie close to the line y=αx in the complex plane, i.e. points z on the lattice such that Im(z)/Re(z) ≈ α.
Here, with α=√3, we want to solve the same problem, i.e. find rational numbers p/q close to α, except that p/q must further be of the form (ad-bc)/(ac+bd) for some (a, b, c, d). Here's the thing: this is precisely the same as saying that (q + ip) is not a Gaussian prime! This is because (a-ib)(c+id) = (ac+bd) + i(ad-bc). (https://en.wikipedia.org/w/index.php?title=Brahmagupta%E2%80...) So any (q + ip) of the form (ac+bd) + i(ad-bc) can be written as the product of two Gaussian integers, and vice-versa.
So the relation between the Diophantine approximation problem and this one is that while there we want to find Gaussian integers close to the line Im(z)=αRe(z), here we want to find composite Gaussian integers close to the line Im(z)=αRe(z).
(Note we can get different "best" approximations depending on how we measure closeness; see my other comment here: https://news.ycombinator.com/item?id=18555240 Also, I expect that as denominators get larger, the primes get sparser, so this becomes closer to the usual problem. Of course in the original post linked here, the goal is to find small solutions, so the difference matters.)
One can build arbitrary approximate angles using lattices.
Lets assume we need 50 degrees angle and we have piece of paper with 100x100 cells. We can construct rightangled triangle and seek for closest legs proportion which gives desired angle between one of legs and hypotenuse.
Desired proportion must be rational number closest to tan(50 deg). We can find such rational number by seeking Farey sequence limited with denominator less than 100. So, for this case triangle with 87 and 73 cell legs will give us 50.000644597558434 degrees angle. Looks pretty good result to me.
I think, in case with two non-aligned rays we can reduce it to first case by building two triangles and constructing angle between hypotenuses.