Functions | |
bool | circleWithCirclesector (const Point &circlePos, int circleRadius, const Point &secPos, int secRadius, float secAngle, float secSize) |
bool | diskWithCircleSector (const Point &diskCenter, int diskRadius, const Point §orCenter, int sectorRadius, int halfTopAngle, int placeAngle) |
Checks if a disk and a circle-sector collide. | |
bool | CircleWithCircle (const Point ¢er1, int radius1, const Point ¢er2, int radius2) |
Collision of a Disk with a Circle-Sector. | |
bool | rectWithRect (const Point &pos1, const Point &size1, const Point &pos2, const Point &size2) |
checks if two rectangles intersect |
bool Collision::CircleWithCircle | ( | const Point & | center1, | |
int | radius1, | |||
const Point & | center2, | |||
int | radius2 | |||
) |
Collision of a Disk with a Circle-Sector.
Checks if two circles intersect.
For a detailled explanation of this function please see: http://wiki.themanaworld.org/index.php/Collision_determination
bool Collision::diskWithCircleSector2(const Point &diskCenter, int diskRadius, const Point §orCenter, int sectorRadius, int halfTopAngle, int placeAngle) { Converting the radii to float float R = (float) sectorRadius; float Rp = (float) diskRadius;
Transform to the primary coordinate system float Px = diskCenter.x - sectorCenter.x; float Py = diskCenter.y - sectorCenter.y;
The values of the trigonomic functions (only have to be computed once) float sinAlpha = utils::math::cachedSin(halfTopAngle); float cosAlpha = utils::math::cachedCos(halfTopAngle); float sinBeta = utils::math::cachedSin(placeAngle); float cosBeta = utils::math::cachedCos(placeAngle);
This bounding circle implementation can be used up and until a half-top-angle of +/- 85 degrees. The bounding circle becomes infinitly large at 90 degrees. Above about 60 degrees a bounding half-circle with radius R becomes more efficient. (The additional check for a region 1 collision can then be scrapped.)
Calculating the coordinates of the disk's center in coordinate system 4 float Px1 = Px * cosBeta + Py * sinBeta; float Py1 = Py * cosBeta - Px * sinBeta;
Check for an intersection with the bounding circle (>) : touching is accepted if ((cosAlpha * Px1 * Px1 + cosAlpha * Py1 * Py1 - Px1 * R) > (Rp * Rp * cosAlpha + Rp * R)) return false;
Check for a region 4 collision if ((Px*Px + Py*Py) <= (Rp*Rp)) return true;
Calculating the coordinates of the disk's center in coordinate system 1 Px1 = Px * (cosAlpha * cosBeta + sinAlpha * sinBeta) + Py * (cosAlpha * sinBeta - sinAlpha * cosBeta); Py1 = Py * (cosAlpha * cosBeta + sinAlpha * sinBeta)
Check if P is in region 5 (using coordinate system 1) if ((Px1 >= 0.0f) && (Px1 <= R) && (Py1 <= 0.0f)) { Return true on intersection, false otherwise (>=) : touching is accepted return (Py1 >= -1.0f * Rp); }
Check if P is in region 3 (using coordinate system 1) if ((Px1 > R) && (Py1 <= 0.0f)) { Calculating the vector from point A to the disk center float distAx = Px - R * (cosAlpha * cosBeta + sinAlpha * sinBeta); float distAy = Py - R * (cosAlpha * sinBeta - sinAlpha * cosBeta);
Check for a region 3 collision return ((distAx * distAx + distAy * distAy) <= Rp * Rp); }
Discard, if P is in region 4 (was previously checked) if ((Px1 < 0.0f) && (Py1 <= 0.0f)) return false;
float tan2Alpha = utils::math::cachedTan(2 * halfTopAngle);
Check if P is in region 1 (using coordinate system 1) if ((Px1 >= 0.0f) && (Py1 >= 0.0f) && (Py1 <= Px1 * tan2Alpha)) { Return true on intersection, false otherwise (<=) : touching is accepted return ((Px * Px + Py * Py) <= (R * R + Rp * Rp + 2.0f * R * Rp)); }
Calculating the coordinates of the disk's center in coordinate system 3 Px1 = Px * (cosAlpha * cosBeta - sinAlpha * sinBeta) + Py * (sinAlpha * cosBeta + cosAlpha * sinBeta); Py1 = Py * (cosAlpha * cosBeta - sinAlpha * sinBeta)
Discard, if P is in region 4 (was previously checked) if ((Px1 < 0.0f) && (Py1 >= 0.0f)) return false;
Check if P is in region 6 (using coordinate system 3) if ((Px1 >= 0.0f) && (Px1 <= R) && (Py1 >= 0.0f)) { Return true on intersection, false otherwise (<=) : touching is accepted return (Py1 <= Rp); }
Check if P is in region 2 (using coordinate system 3) if ((Px1 > R) && (Py1 <= 0.0f)) { Calculating the vector from point B to the disk center float distBx = Px - R * (cosAlpha * cosBeta - sinAlpha * sinBeta); float distBy = Py - R * (cosAlpha * sinBeta + sinAlpha * cosBeta);
Check for a region 2 collision return ((distBx * distBx + distBy * distBy) <= (Rp * Rp)); }
The intersection with the bounding circle is in region 4, but the disk and circle sector don't intersect. return false; }
Definition at line 283 of file collisiondetection.cpp.
bool Collision::diskWithCircleSector | ( | const Point & | diskCenter, | |
int | diskRadius, | |||
const Point & | sectorCenter, | |||
int | sectorRadius, | |||
int | halfTopAngle, | |||
int | placeAngle | |||
) |
Checks if a disk and a circle-sector collide.
halfTopAngle | The half-top-angle of the circle sector in degrees (0,359). | |
placeAngle | The placement-angle of the circle sector in degrees (0,359). |
Definition at line 86 of file collisiondetection.cpp.
References Point::x, and Point::y.
Referenced by Being::performAttack(), and Monster::update().