Spacing out overlapping rectangles: how to translate pseudocode?

29 views Asked by At

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:

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?

0

There are 0 answers