Skip to content Skip to sidebar Skip to footer

Force Directed Layout For Constrained Rectangular Shapes

I need to evenly distribute a bunch of axis-aligned sliding rectangles constrained by a maximum width/height and by some horizontal/vertical coordinates depending from the position

Solution 1:

If I get this question right OP asks for set of rules for driving the sliders so the final simulation state is leading to valid solution.

So here is my approach it is really recapitulation of my solver code from linked answer in OP but it would not fit in there as I already hit the 30 KByte limit and I feel it needs a bit more explaining then just commented code so here it is:

  1. Forces

    To ensure equal spacing as much as possible you need to change the rules a bit (apart from real physics) so you are accounting only the nearest obstacle to driving Force instead of all of them as in real world. Also the force is affected only by distance and not weighted also by area of contact/overlap as most physical forces do (electrostatic included).

    So during iteration of i-th slider (Yellow) find the distances to closest obstacle in all 4 directions (Red):

    closest neighbors

    And compute the driving force which has to be scaled with distance. Does not really matter if linearly or not but for evenly spaced obstacles from left/right or up/down should be the resultant force zero. Scaling changes mostly the dynamics behavior. The final outcome is affected by it only in states where constrains blocks the movement to achieve even spacing. So you can use for example any of these:

    F = c * (d1-d0)
    F = c * (d1^2 - d0^2)
    F = c * (1/d1^2 - 1/d0^2)
    

    Where c is some magnitude coefficient and d0,d1 are the 2 closest obstacle distances in the same axis.

    Now from this you will obtain 2 forces (one for each axis)

    • Fx - horizontal axis force
    • Fy - vertical axis force

    In a nutshell that is it. But there is a problem with the constrains. For example selected slider (Yellow) is vertical. That means it can move only in x axis. So you put the Fx driving force to it. The Fy force should drive its parent slider (Blue) which is horizontal and can move in y axis (if not fixed of coarse).

    This introduce a problem because that slider can also have its own Fy so you should always select only the strongest force from each side. That means you need to remember both distances/forces from each side and select always the smallest distance or |highest| force from each side.

    That is where the x0,x1 variables come from they hold the min distance in movement able axis to nearest obstacles (from child included) and only after computation of all sliders are converted to Fx,Fy driving forces.

    To detect neighbors and collisions I recognize 3 types of interaction

    • perpendicular which is between horizontal and vertical slider (bottom interaction on image)
    • wide parallel which is between two sliders of the same type contacting with its longer sides (left,right interaction on image)
    • short parallel which is between two sliders of the same type contacting with its shorter sides (top interaction on image)
  2. Limits and coefficients

    I also introduced some speed limits and coefficients (not just for dumping to avoid oscillations). The speed and acceleration limits affects the solution time and stability. There is also another reason to use them (I do not do) and that is to preserve the order of sliders so they do not skip through each other. That can be done by simply limiting the top speed so per single iteration any slider will not move more then the half of thickness of sliders. So in case of collision the collision routine will kick in.

    I am skipping that in my code because my config is set so the order of sliders is consistent with its index number. So if I detect that any slider is on left side of some tested slider while its index is higher it means it has skipped and I handle it by restoring last position instead... This is cheap hack and will not work in complex sets where are many child sliders in chain not just one.

  3. Feedback

    Due to constraints sometimes your driving force can get lost (traveling to fixed or stuck parent slider) in case this behavior corrupts the result you should propagate opposite force the other way around too to the neighbor it caused it. For simple constructs is this not necessary as the driving force it already contain but for more complicated children chains It could pose a possible threat (but that is my wild thinking and I may be wrong in this). In nature this is provided by integrating force from all of the neighboar objects instead of just the closest ones but that would lead to non equal spacing I think.

Post a Comment for "Force Directed Layout For Constrained Rectangular Shapes"