I'm working on fixing the flee AI that I wrote a long time ago so that it is a bit smarter at avoiding enemies but I'm a bit stuck. What I'm trying to do is something like the following:
1. Look at the position of all of the attackers of the AI and generate an orientation vector to each one.
2. From these orientation vectors, calculate a new "escape vector" that optimally avoids all of the enemies as best as possible.
I have an idea of how to potentially make this work but I'm unsure of how to correctly calculate everything. Let me give an example taken directly from what I have so far. This picture shows the vectors from the target to all of the enemies that are attacking it (white lines), which are being rendered in real time by Ogre, and I've drawn in a sample vector that should be calculated to avoid everyone (red line). it's important to note that I'm not 100% sure that the line I drew is the correct escape vector for this example. Since there are two large areas that are fairly close in size there could potentially be multiple solutions, so keep that in mind. But for now, let's just assume the red line I drew is the one solution for this example to simplify things.
The current idea I have of calculating this escape vector is by doing something like the following:
1. Get the angle between every possible combination of the vectors, essentially splitting up a circle into wedges that are defined by the vectors to the enemies.
2. Compare the wedges and find the one with the largest angle. This is where the multiple solutions would come in. If there are multiple wedges very close in size then it would probably have to randomly pick one.
3. Calculate a vector that bisects the selected wedge, which will be the escape vector pictured in red.
So if we redraw the original example to show a circle you can more clearly see all of the wedges that are created by the various vectors: How would I go about doing something like this? I'm unsure of how to split up the circle. Would you use the dot product of the vectors or something? That's what I'm currently trying to do but I'm not sure what to do with the results.
Here's a code example to show you what I have so far. This loop gets the dot product of every possible combination of the vectors available.
Code: Select all
// This container gets populated elsewhere. It contains the normalized orientation vectors from the target to each enemy attacking it
// (all of the white lines in the sample pictures). It's important to note that they are not sorted in any particular order, but they could easily
// be if that makes some part of the algorithm easier.
std::vector<Ogre::Vector2> enemyOrientationVectors;
for (std::vector<Ogre::Vector2>::const_iterator iter(enemyOrientationVectors.cbegin()), backIter(--enemyOrientationVectors.cend()); iter != backIter; ++iter)
{
for (std::vector<Ogre::Vector2>::const_iterator nextIter(iter + 1), endIter(enemyOrientationVectors.cend()); nextIter != endIter; ++nextIter)
{
const Ogre::Real dotProduct(iter->dotProduct(*nextIter));
// Some debug output to see the dot product and angle of each combination.
gDOS << "dot of " << iter - enemyOrientationVectors.cbegin() << " and " << nextIter - enemyOrientationVectors.cbegin() << ": " << dotProduct << " Angle: " << Ogre::Radian(acos(dotProduct)).valueDegrees() << "\n";
// TODO: Do something with the dot product to figure out which combination of vectors generates the best results, or maybe calculate something else? Not sure...
}
}
Code: Select all
Targeter angles: 167.005 156.801 153.435 -118.811 135 147.995 -146.31 155.376 -18.4349
dot of 0 and 1: 0.984183 Angle: 10.204
dot of 0 and 2: 0.972082 Angle: 13.5704
dot of 0 and 3: 0.272552 Angle: 74.1838
dot of 0 and 4: 0.847998 Angle: 32.0054
dot of 0 and 5: 0.945457 Angle: 19.0108
dot of 0 and 6: 0.686013 Angle: 46.6847
dot of 0 and 7: 0.979474 Angle: 11.6289
dot of 0 and 8: -0.995495 Angle: 174.56
dot of 1 and 2: 0.998274 Angle: 3.36645
dot of 1 and 3: 0.0977948 Angle: 84.3878
dot of 1 and 4: 0.928477 Angle: 21.8014
dot of 1 and 5: 0.98821 Angle: 8.80678
dot of 1 and 6: 0.546268 Angle: 56.8887
dot of 1 and 7: 0.999691 Angle: 1.42491
dot of 1 and 8: -0.996546 Angle: 175.236
dot of 2 and 3: 0.0391856 Angle: 87.7542
dot of 2 and 4: 0.948683 Angle: 18.4349
dot of 2 and 5: 0.995495 Angle: 5.44032
dot of 2 and 6: 0.496139 Angle: 60.2551
dot of 2 and 7: 0.999426 Angle: 1.94149
dot of 2 and 8: -0.989949 Angle: 171.87
dot of 3 and 4: -0.27881 Angle: 106.189
dot of 3 and 5: -0.0557272 Angle: 93.1946
dot of 3 and 6: 0.887018 Angle: 27.4991
dot of 3 and 7: 0.0730159 Angle: 85.8128
dot of 3 and 8: -0.180104 Angle: 100.376
dot of 4 and 5: 0.974391 Angle: 12.9946
dot of 4 and 6: 0.196116 Angle: 78.6901
dot of 4 and 7: 0.937425 Angle: 20.3764
dot of 4 and 8: -0.894427 Angle: 153.435
dot of 5 and 6: 0.411587 Angle: 65.6954
dot of 5 and 7: 0.991712 Angle: 7.3818
dot of 5 and 8: -0.972082 Angle: 166.43
dot of 6 and 7: 0.525269 Angle: 58.3136
dot of 6 and 8: -0.613941 Angle: 127.875
dot of 7 and 8: -0.994172 Angle: 173.811