3
$\begingroup$

This is a problem which has tripped me up for some time. Given an $(n\times m)$ grid, one has the possibility to choose all possible permutations of three points, and this would then give all possible triangles within that grid, eg: for a $(5\times 5)$ grid:

    (* Mathematica code *)

    grid = Flatten[Table[{i,j},{i,5},{j,5}],1];
    triangles = Permutations[grid,{3}];

This gives 13769 possible combinations. Now if I were looking at a $(1000\times 1000)$ grid, things would get excessively large. So instead, I want to figure out a quick way to generate triangles - defined by coordinates $((x_1,y_1),(x_2,y_2),(x_3,y_3))$ - which belong to an equivalence class. This equivalence class is defined by the length of each side $(r^2_{12},r^2_{13},r^2_{23})$. For example:

The points $((1,1),(3,4),(2,5))$ belong to the equivalence class $(2,25,29)$. Naturally we could rotate this triangle and it would technically form a new set of points, thus a new triangle, but still belong to the same equivalence class. Furthermore, the points $((1,1),(4,3),(2,5))$ form a totally different triangle. Yet, still belong to that equivalence class. My problem can thus be broken down into two parts:

  • Find all possible and unique set of equivalence classes within a given grid.
  • Generate three coordinate points (within the boundary of a grid or array) which form a triangle belonging to that particular equivalence class.
    • Bonus would be to find ALL possible unique triangle instances which belong to that equivalence class, but for now it would not be necessary.

A preliminary solution for the first problem would be to list the square of all possible lengths on a 2D lattice $(1,2,4,5,8,9,13,16,17,...)$ - which I have my own code to do so, and then find all the unique 3-tupples of this list. Going this route brings two problems:

  1. Not all tupples within this list give a valid equivalence class of a triangle on a lattice - e.g $(1,2,4)$
  2. I would need another bit of code to test whether such an equivalence class generates a valid triangle.

Thus far, I have settled with generating random triangles and binning them in whatever equivalence class they happen to form. Unfortunately, although relatively quick, it is not uniform enough, and it destroys my memory. For my purposes I need some fine structure, this relates to generating an even spread of triangles across all possible equivalence classes within the grid.

NB since I am dealing with really large grids, speed here is extremely important.

Lastly, I appreciate the fact that sometimes no matter how quick some code my be, due to the sheer size of certain operations it will always take time.

  • 0
    You might instead ask about this problem on [Math.SE] and then implement what you learn in *Mathematica*. If you would like I can move this question there for you.2017-02-26
  • 0
    I hadn't considered posting it as a mathematical problem as I thought it may have been somewhat trivial. The way it's phrased is in a coding context however, would it still be suitable in the mathematics forum? If so, then I'm happy if you move it over.2017-02-26
  • 0
    To the best of my knowledge this should be on-topic for [Math.SE]. I shall perform the migration. If that community disagrees and rejects the migration (closes the question) I shall reopen this one.2017-02-26
  • 0
    Perhaps a simpler form of the problem would produce some good insights. I would think about the choices for the longest side of the "lattice triangle", noting that one of its two endpoints could always be chosen to be a specified corner of the grid.2017-02-27
  • 1
    You must be explicit in your definition of *equivalence class* by stating what transformations leave a triangle "invariant." I gather you allow two-dimensional (lattice) translation, rotation and flip symmetry. That reduces your search immensely, and also allows you to put one vertex at the origin $(0,0)$.2017-02-27
  • 0
    @DavidG.Stork Yes, apologies, I should have been a bit more explicit by how I define my equivalence class. As you correctly stated, there is translational, rotational and flip symmetry. But you would still have to go through every possible triangle and then throw out the which ever equivalence classe you've already come by? Or am I missing some consequence of the symmetries that mean I only need to scan a portion of points on the grid?2017-03-01

1 Answers 1

2

This is more of a comment

Sorry I don't have time or expertise for a more thorough answer, but here are some tips:

Whenever I'm presented with a problem like this, I try to formulate a canonical way to construct things so that duplicates won't exist. In this case, we want to eliminate rotational, reflectional and translation symmetries.

  • Eliminating reflectional symmetries: make edges increase in length as you go clockwise around the triangle. i.e. lengths $(2,3,1)$ as you go around clockwise.
  • For a square grid, $n \times n$, you can eliminate rotational symmetries by making sure that the inward-pointing normal vector (pointing in to the triangle) of the longest edge lies in a particular quadrant. This is because only four rotations are possible on a Euclidean grid.
  • Eliminating translational symmetries: translate any triangle you construct to lie as far in the bottom left corner as possible while still fitting inside your grid.

Now if we require that the inward-pointing normal of the longest edge lie in the $[0,\pi/2)$ quadrant, then the two endpoints of the longest edge are what determine how far to the bottom-left we can shift the triangle. One of them will be pushed all the way to the left of the grid, and the other all the way to the bottom.

Constructing unique triangles:

  1. Pick two points on the left and bottom of the grid respectively. i.e. if $(0,0)$ is the bottom left corner, then $(0,5)$ and $(0,0)$ is an acceptable choice.
  2. From our requirement that the edges get longer as we go clockwise, we rule out many of the points on which we could have placed the third vertex.
  3. Every other vertex not ruled out from 2. will produce a distinct triangle.

Following this procedure, a single triangle from each equivalence class should have been constructed.


Here's an example. I should have used a square grid as per my above reasoning.

enter image description here

  1. I pick two points on the left and bottom of the grid (the circled points).
  2. I draw (closed) circles around each of the two endpoints of the line produced by these two points (this is our longest edge), and eliminate any points outside of either one of these circles, as this would produce an edge longer than this one we just made. I crossed out these points.
  3. Since we want the edges to increase in length as we go clockwise, this rules out a symmetric half of the remaining viable domain. The half that we can rule out is shaded. The shaded region is open in the sense that points lying on the boundary are okay (these produce isosceles triangles).
  4. Any choice of a third vertex from the remaining candidate points should produce a valid and unique triangle, as all symmetries have been accounted for (at least for a square $n \times n$ grid. More thought is required with regard to rotations for $m \times n$).

Do let me know if something's wrong in my reasoning. I think this is right though.