/
corners.py
120 lines (99 loc) · 4.5 KB
/
corners.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import utils
import os
# Corners will remain fixed during the GA process
# We will use this to set the corners, and pass it into the first solution
def writeFormulasToFile(cornerSquareInfo):
if os.path.exists("outputs/corners.txt"):
os.remove("outputs/corners.txt")
with open("outputs/corners.txt", "w") as f:
for corner in cornerSquareInfo:
f.write(str(len(corner)) + " corners\n")
formulas = [utils.writeDesmosFormulas(square) for square in corner]
for formula in formulas:
f.write("\n".join(formula) + "\n")
f.close()
def readCornersFromFile(filename):
with open(filename) as f:
corners = []
for line in f:
squares = []
for coordinate in line.split(";"):
x, y = coordinate.split(",")
squares.append((int(x), int(y)))
corners.append(squares)
corners = [moveCornerTo100(corner, i) for i, corner in enumerate(corners)]
corners = getCornerSquareInfo(corners)
return corners
# returns a nested list of squares that are in the corners
# uses a generation function to generate the squares, can define new ones to try different corner configs
# cornerIndex 0 is top left, move clockwise
def assembleCornerSquares(cornerSquares, generationFunction):
squares = [generationFunction(cornerSquares[i], i) for i in range(4)]
squares = [moveCornerTo100(corner, i) for i, corner in enumerate(squares)]
squares = getCornerSquareInfo(squares)
return squares
# build squares from corner, layer by layer
# return top-left corners of the squares
def generateFromInsideOut(numSquares, cornerIndex):
squares = []
cornerMultiplier = [(1, -1), (-1, -1), (-1, 1), (1, 1)]
level = 0
while len(squares) < numSquares:
i = 0
while i < level and len(squares) < numSquares:
coordinate = tuple(val1 * val2 for val1, val2 in zip(cornerMultiplier[cornerIndex], (i, level - i)))
squares.append(coordinate)
i += 1
level += 1
return squares
# move the corner to respective (100, 100)
def moveCornerTo100(topLeftCoordinates, cornerIndex):
if cornerIndex == 0:
# top left
movedCoordinates = [(x - 100, y + 101) for x, y in topLeftCoordinates]
elif cornerIndex == 1:
# top right
movedCoordinates = [(x + 99, y + 101) for x, y in topLeftCoordinates]
elif cornerIndex == 2:
# bottom right
movedCoordinates = [(x + 99, y - 100) for x, y in topLeftCoordinates]
else:
# bottom left
movedCoordinates = [(x - 100, y - 100) for x, y in topLeftCoordinates]
return movedCoordinates
def getCornerSquareInfo(cornerSquares):
cornerSquareInfo = []
for corner in cornerSquares:
thisCorner = [utils.getSquareInfo((coordinate, 0, 0)) for coordinate in corner]
cornerSquareInfo.append(thisCorner)
return cornerSquareInfo
# cornerSquares is a list of 4 arrays of 3-tuples (lines, corners, d); started at (100, 100) for each corner
# this method finds and keeps the squares that are facing inwards; only these squares will "touch" the middle squares
# we find the inner-facing squares by checking whether the inner-facing corner has an adjacent square that is closer to the center
def filterCornersForInnerFacingSquaresOnly(cornerSquares):
closerToCenter = [(1, -1), (-1, -1), (-1, 1), (1, 1)]
filteredCorners = [[], [], [], []]
for i in range(len(cornerSquares)):
innerFacingCornerIndex = (i + 2) % 4
squares = cornerSquares[i]
for sq in squares:
_, corners, _ = sq
innerCorner = corners[innerFacingCornerIndex]
closerCorner = (innerCorner[0] + closerToCenter[i][0], innerCorner[1] + closerToCenter[i][1])
closerToX = (innerCorner[0] + closerToCenter[i][0], innerCorner[1])
closerToY = (innerCorner[0], innerCorner[1] + closerToCenter[i][1])
foundCloser = False
foundX = False
foundY = False
for sq2 in squares:
corner2 = sq2[1][innerFacingCornerIndex]
if corner2 == closerCorner:
foundCloser = True
break
if corner2 == closerToX:
foundX = True
if corner2 == closerToY:
foundY = True
if (not foundCloser) and not (foundX and foundY):
filteredCorners[i].append(sq)
return filteredCorners