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:
- 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
- Re-order the
circle(1 to x, 1 to 3)
array by dimension 2 (i.e. sorting the circle by .Top) - 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.
- Connect the circles to their corresponding rectangle with an
msoConnectorElbow
. Where there is only a smallshape.Top
differential between the rectangle and the circle then I connect them withmsoConnectorStraight
.
The result is relatively pleasing. Please see image pasted below.
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?