1
votes

I have a list of vertices from a polygon and I'm trying to create an equilateral triangular grid inside a larger triangle centered around the current vertex from the input polygon.

The size of the internal triangle's sides is determined by L which divides the container side to L equal parts. Finally I'd like to store the coordinates of the vertices of all these triangles (including the original larger triangle) in a list in Python.

Desired result

One approach I have come up with is the following:

  • Find equidistant points with respect to L on each side of the large triangle
  • Connect these points to the adjacent larger side
  • Create a Shapely LineString from each of corresponding points
  • Run a for loop that utilizes Shapely's object.intersection() function that returns the coordinates

However I'm open to ideas and other approaches possibly more efficient ones.

Here's my code so far:

import math
import sys


# Constructs the larger, container triangle given the centroid (a vertex from the input polygon)
def construct_eq_triangle(centroid, radius):
    side_length = radius * math.sqrt(3)
    # Calculate three vertices of the container triangle
    a = [centroid[0], centroid[1] + (math.sqrt(3) / 3) * side_length]  # Top vertex
    b = [centroid[0] - (side_length / 2), centroid[1] - (math.sqrt(3) / 6) * side_length]  # Bottom left vertex
    c = [centroid[0] + (side_length / 2), centroid[1] - (math.sqrt(3) / 6) * side_length]  # Bottom right vertex

    return a, b, c


def draw_triangular_grid(vertex, radius, L):

    grid_x = []
    grid_y = []
    
    # contruct the container equilateral triangler around this vertex
    a, b, c = construct_eq_triangle(vertex, radius)
    # Draw the grid here inside a,b,c and fill 'grid_x' and 'grid_y'
   
    # but for now just print the mother triangle
    print("\n Equilateral triangle for vertex " + str(vertex) + ":")
    print((a, b, c))

    return grid_x, grid_y


def main(args):
    # demo data, 4 vertices of a simple square with a length of 8
    vertices = [(2.0, 10.0), (10.0, 10.10), (10.0, 2.0), (2.0, 2.0)]
    radius = 2
    L = 7
    i = 0
    while i <= len(vertices) - 1:
        grid_x, grid_y = draw_triangular_grid(vertices[i], radius, L)
        # process the grid coordinates
        i += 1


# Main entry point
if __name__ == "__main__":
    main(sys.argv[1:])


1

1 Answers

3
votes

If you need to calculate triangle vertices:

import math

ax = 0
ay = 100
L = 4
tri = []
Size = 100
dx = 0.5 * Size / L
dy = - math.sqrt(3) * dx

for i in range(L):
    basex = ax - dx * i
    basey = ay + dy * i
    tri.append([(basex, basey), (basex - dx, basey + dy), (basex + dx, basey + dy)])
    for j in range(i):
        tri[-1].extend([(basex + j * 2 * dx, basey),
                        (basex + j * 2 * dx + dx, basey +   dy),
                        (basex + (j + 1) * 2 * dx, basey)])
        tri[-1].extend([(basex + (j + 1) * 2 * dx, basey),
                        (basex + (j + 1) * 2 * dx - dx, basey + dy),
                        (basex + (j + 1) * 2 * dx + dx, basey + dy)])

for i in range(L):
    print(tri[i])
    print()

Result contains stripes of triangles as triplets of vertex tuples:

[(0.0, 100.0), (-12.5, 78.34936490538904), (12.5, 78.34936490538904)]

[(-12.5, 78.34936490538904), (-25.0, 56.698729810778076), (0.0, 56.698729810778076),
 (-12.5, 78.34936490538904), (0.0, 56.698729810778076), (12.5, 78.34936490538904), 
 (12.5, 78.34936490538904), (0.0, 56.698729810778076), (25.0, 56.698729810778076)]

[(-25.0, 56.69872981077807), (-37.5, 35.0480947161671), (-12.5, 35.0480947161671), 
 (-25.0, 56.69872981077807), (-12.5, 35.0480947161671), (0.0, 56.69872981077807), 
 (0.0, 56.69872981077807), (-12.5, 35.0480947161671), (12.5, 35.0480947161671), 
 (0.0, 56.69872981077807), (12.5, 35.0480947161671), (25.0, 56.69872981077807), 
 (25.0, 56.69872981077807), (12.5, 35.0480947161671), (37.5, 35.0480947161671)]

[(-37.5, 35.0480947161671), (-50.0, 13.397459621556134), (-25.0, 13.397459621556134), 
 (-37.5, 35.0480947161671), (-25.0, 13.397459621556134), (-12.5, 35.0480947161671), 
 (-12.5, 35.0480947161671), (-25.0, 13.397459621556134), (0.0, 13.397459621556134), 
 (-12.5, 35.0480947161671), (0.0, 13.397459621556134), (12.5, 35.0480947161671), 
 (12.5, 35.0480947161671), (0.0, 13.397459621556134), (25.0, 13.397459621556134), 
 (12.5, 35.0480947161671), (25.0, 13.397459621556134), (37.5, 35.0480947161671), 
 (37.5, 35.0480947161671), (25.0, 13.397459621556134), (50.0, 13.397459621556134)]