I've got bots in a rectangular formation with rows and columns. A problem arises when a bot is added or removed from the formation. When this happens, the bots have to rearrange themselves so that the rectangular formation is still roughly the same aspect ratio, and is as rectangular as possible. How to do this?
Some ideas:
When a bot is added or removed, use the new total number of bots and a desired constant aspect ratio to calculate the new width and height of the formation that most closely fits that aspect ratio. Then somehow reshuffle the bots to fit the new dimensions.
When a bot is removed, move the bot that was behind it into it's place, and continue until you reach the end of the formation. Then even out the back rank as much as possible by somehow shuffling the bots in the back rank.
Another idea that's completely different is to mimic the way molecule structures stay together. Make every bot want to be surrounded by four other bots by attracting the four closest bots, and repelling the rest. Repel all bots (including the four) that are too close to ensure separation using inverse square law. You'd also need an additional force to shape of the entire structure. But, this sounds very computationally expensive.
UPDATE: So looking into sarahm's answer, I came up with a good general function that gives good dimensions.
First I solved the below simultaneous equation for width and height, and then rounded the answers.
width/height=aspect ratio of your choice
width*height=number of bots
This gives you the closest integer rectangle to that aspect ratio for your number of bots. The closest rectangle will half the time be a too large, and half the time be a too small (of course sometimes it will be just right but who cares about those). In the cases where the rectangle is a little too large, nothing needs to be done. The back rank will just end up being almost full, which is ideal. In the cases where the rectangle is a little too small, you got problems because that teeny tiny overflow will have to go to its own rank created a rank with only a few bots on it, which doesn't look pretty. There are also cases where the difference is large (larger than half the width), in which case add or subtract one rank to make the difference small. Then, when the rectangle is too small, add one column to make it just a little bit larger. After doing that it looks like the back rank will always have at least half as many bots as the other ranks.
UPDATE
Once you got the dimensions, compare them to the current dimensions. If the frontage of the new dimension is bigger, for every rank, pop bots from the rank below, and push them onto the current rank until that the number of bots on that rank is equal to the frontage. Continue that algorithm until you get to the back rank. Using this algorithm, bots will move to fit into the new dimension efficiently. After that, I simply push the new old onto the back rank. The algorithm is slightly different for the cases where the new frontage is smaller, but you can figure it out!
There's two more problems next. Deletion, and a more flexible addition method where new bots are not necessarily assigned to the back rank but whichever position is closest to them at the moment they are added.
Answer
Another technique is to mimic that used by Napoleonic battalions (and probably as far back as Greek phalanxes if not further).
Frontage is generally maintained constant, and as a man falls (in any rank except the back) he is replaced by the man directly behind him stepping forward. The back rank is shuffled by the NCO's to ensure a few men at the extreme of each flank, and otherwise to fill in evenly.
The frontage is only reduced when the back rank falls below pre-specified densities. Likewise, when the back rank is overfull the extras first start filling in an additional rank from both flanks in, and then the frontage is increased.
When changing frontage, I suggest having your bots file out from the back rank to both flanks when increasing frontage, and filing in from both flanks to the back rank when reducing frontage.
If I am correct in inferring that you are looking for a "military" impression, and having your bot organizations look like phalanxes, I believe this ordered re-arrangement is a better way to achieve that end.
Update:
One simple way to manage the back row is to divide the back-row units into three squads: one on each flank and one in the centre. Depending on whether the frontage is odd or even, and whether the number of back-row units is congruent to 0,1,or 2 mod 3, there are exactly six cases to manage.
As an enhancement to the above, consider spacing the last unit(s) of each back-row squad once the fill drops below a threshold, like this:
xxx.x....x.xxx.x....x.xxx
or this:
xx.x.x...x.xxx.x...x.x.xx
A bit more work, for an even better appearance.
Update #2:
An additional thought on formation depth. The impact of volley fire, combined with the modern bayonet, made depths of 3 or 4 adequate in the late 18th and early 19th century. (The British rarely fought in 2 ranks, contrary to popular belief, until late in a battle; for one, it made their lines too long to form square quickly.) Prior to that it was common to have greater depths, perhaps up to 8 or 10 for a Greek phalanx equipped with Sarissa. Choose a depth that creates the impression you desire.
Armies in real life try to maintain unit frontage as long as possible, at the expense of increased unit brittleness, as this makes laying out a battlefield simpler. Caesar at Pharsalus deliberately reduced his unit depth to increase frontage to match that of Pompey's forces. As the quote goes: "We win or die today; Pompey's men have other choices." (which Caesar had cleverly and carefully ensured, of course).
No comments:
Post a Comment