1

I am generating a number of circles on a PowerPoint slide. Their placement is fixed (i.e. they cannot be moved around). I then connect them to call-out rectangles that I align on the right hand side of the slide. Pseudo code is as follows:

  1. Generate an circle(1 to x, 1 to 3) array for the circles, where dimension '1' is the circle, .Name, dimension '2' is the circle .Top and dimension '3' is the circle .Left
  2. Re-order the circle(1 to x, 1 to 3) array by dimension 2 (i.e. sorting the circle by .Top)
  3. Loop through the array and generate an associated rectangle for each circle and I lay them out programmatically to desired height and position on the RH side of the slide.
  4. Connect the circles to their corresponding rectangle with an msoConnectorElbow. Where there is only a small shape.Top differential between the rectangle and the circle then I connect them with msoConnectorStraight.

The result is relatively pleasing. Please see image pasted below. enter image description here

Problem. As you shall see, some of the msoConnectorElbow collide (e.g. first three circles). My question is as follows: how should I sort the circles such that the msoConnectorElbow no longer collide? Clearly I would need an optimization algorithm. My initial idea was to partition the array into two (e.g. identify the 'median' circle) and then iterate through each bit of the array again and again such that the elbows do not collide.

Pseudo code for the first 'half' of the array would look something like this (apologies, it's a bit hacky and relies on a helper array):

Pivot = UBound(countries) / 2

For i = 1 To Pivot - 1
    For z = i + 1 To Pivot

    If (circles(i, 2) - circles(z, 2)) < 0 And (circles(i, 3) - circles(z, 3)) > 0 Then

    'switch the two circles in a 'helper array'
    final_array(z, 1) = circles(i, 1)
    final_array(z, 2) = circles(i, 2)
    final_array(z, 3) = circles(i, 3)
    final_array(i, 1) = circles(z, 1)
    final_array(i, 2) = circles(z, 2)
    final_array(i, 3) = circles(z, 3)

    'amend the original array
    circles(z, 1) = final_array(i, 1)
    circles(z, 2) = final_array(i, 2)
    circles(z, 3) = final_array(i, 3)
    circles(i, 1) = final_array(z, 1)
    circles(i, 2) = final_array(z, 2)
    circles(i, 3) = final_array(z, 3)

    End If

    Next
Next

What ultimately happens when I run this to completion is a complete reordering of the circles by horizontal dimension... Which in the end creates perhaps even more colliding elbow connectors, etc.

What would be the appropriate algorithm to address my issue and properly order my array to optimize the placement of the rectangles?

1 Answer 1

1

I think you could essentially avoid collision if you're allowed to change the order that the lines are connected to the dots.

Keep searching for the farthest right dot and connect it to the box center that it is closest to (in terms of absolute up/down distance) and repeat.

enter image description here

Sorry about the diagram being messy, I had to do it in paint!

Sign up to request clarification or add additional context in comments.

2 Comments

You either have a very fresh pair or eyes or a beautiful mind. Your answer is perfect. I wish I could have seen that myself.
I hope my end wont be as tragic as Nash's!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.