I've been trying to port some Mathematica/pseudocode from this answer to Python/Blender (the question's conditions are virtually identical to mine). The answer has two edits, each with a different version of the same algorithm. I've ported the first, but am struggling with the second.
The first edit in Python is this:
stack = deque()
while any(intersections[r] for r in rectangles):
rectangles.sort(key=lambda r: intersections[r])
stack.appendleft(rectangles[0])
del rectangles[0]
while stack:
rectangles.insert(0, stack[0])
stack.popleft()
rect = rectangles[0]
g = geometric_centre(points)
b, d = points[rect]
m = ((b + d) / 2) - g
i = 1
while has_intersections(rect, points):
x = (-1)**i * i * INCR
vec = Vector((x, x)) * m
b += vec
d += vec
i += 1
Here points is a dictionary of each rectangle to a tuple of two mathutils.vectors representing its top-right and bottom-left corners.
Before/after:
But I'm having trouble porting the improved "multi-angle searching" pseudocode from the second edit, in which the second while loop is now:
While stack not empty
find the geometric center G of the chart (each time!)
find the PREFERRED movement vector M (from G to rectangle center)
pop rectangle from stack
With the rectangle
While there are intersections (list+rectangle)
For increasing movement modulus
For increasing angle (0, Pi/4)
rotate vector M expanding the angle alongside M
(* angle, -angle, Pi + angle, Pi-angle*)
re-position the rectangle accorging to M
Re-insert modified vector into list
Since the answer didn't include the source code, I'm unclear on its meaning. Here was my abortive attempt:
while stack:
rectangles.insert(0, stack[0])
stack.popleft()
rect = rectangles[0]
g = geometric_centre(points)
b, d = points[rect]
m = ((b + d) / 2) - g
old_m = m.copy()
while has_intersections(rect, points):
for i in range(1, abs(int(m.magnitude))):
for angle in (15, 30, 36, 45):
m.rotate(Matrix.Rotation(radians(angle), 2))
b += old_m - m
d += old_m - m
How would I translate the pseudocode into Python?
