Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/helpers/Geometry.cpp
Show First 20 Lines • Show All 180 Lines • ▼ Show 20 Lines | if (dv < fixed::Zero()) // F, H | ||||
corner -= v.Multiply(hh); | corner -= v.Multiply(hh); | ||||
else // A, C | else // A, C | ||||
corner += v.Multiply(hh); | corner += v.Multiply(hh); | ||||
return corner; | return corner; | ||||
} | } | ||||
} | } | ||||
fixed Geometry::DistanceSquareToSquare(const CFixedVector2D& relativePos, const CFixedVector2D& u1, const CFixedVector2D& v1, const CFixedVector2D& halfSize1, const CFixedVector2D& u2, const CFixedVector2D& v2, const CFixedVector2D& halfSize2) | |||||
{ | |||||
/* | |||||
* The shortest distance between two non colliding squares equals the distance between a corner | |||||
* and other square. Thus calculating all 8 those distances and taking the smallest. | |||||
temple: Unless they're overlapping in a weird way (two rectangles in a cross), but that's unlikely to… | |||||
Not Done Inline ActionsTrue, but do notice this is already counted as 0, since at least 1 corner will be inside the other square (and we set the last argument to true) bb: True, but do notice this is already counted as 0, since at least 1 corner will be inside the… | |||||
Not Done Inline ActionsI'm saying if you have two long rectangles overlapping in a cross, like +, then they only overlap in the center, so none of the corners of one rectangle will be inside the other rectangle. It should be distance = 0 but instead will be something > 0. We won't often/ever have rectangles overlapping like this so it's not really a concern. (Units are circles, so rectangle vs rectangle would have to be something like fort vs fort, and they'll never overlap.) temple: I'm saying if you have two long rectangles overlapping in a cross, like +, then they only… | |||||
Not Done Inline ActionsHow could I miss that, we can simply test for TestSquareSquare avoiding this issue bb: How could I miss that, we can simply test for TestSquareSquare avoiding this issue | |||||
* For colliding squares we simply return 0. When one of the points is inside the other square | |||||
* we depend on DistanceToSquare's countInsideAsZero. When no point is inside the other square, | |||||
* it is enough to check that two adjacent edges of one square does not collide with the other square. | |||||
*/ | |||||
fixed hw1 = halfSize1.X; | |||||
fixed hh1 = halfSize1.Y; | |||||
fixed hw2 = halfSize2.X; | |||||
fixed hh2 = halfSize2.Y; | |||||
if (TestRaySquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2) || | |||||
TestRaySquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2)) | |||||
return fixed::Zero(); | |||||
return std::min(std::min(std::min( | |||||
DistanceToSquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | |||||
DistanceToSquare(relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true)), | |||||
std::min( | |||||
DistanceToSquare(relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | |||||
DistanceToSquare(relativePos - u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true))), | |||||
Not Done Inline Actionsminus u2 temple: minus u2 | |||||
Not Done Inline ActionsWoot woot bb: Woot woot | |||||
std::min(std::min( | |||||
DistanceToSquare(relativePos + u2.Multiply(hw2) + v2.Multiply(hh2), u1, v1, halfSize1, true), | |||||
DistanceToSquare(relativePos + u2.Multiply(hw2) - v2.Multiply(hh2), u1, v1, halfSize1, true)), | |||||
std::min( | |||||
DistanceToSquare(relativePos - u2.Multiply(hw2) + v2.Multiply(hh2), u1, v1, halfSize1, true), | |||||
DistanceToSquare(relativePos - u2.Multiply(hw2) - v2.Multiply(hh2), u1, v1, halfSize1, true)))); | |||||
} | |||||
fixed Geometry::MaxDistanceToSquare(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | |||||
{ | |||||
fixed hw = halfSize.X; | |||||
fixed hh = halfSize.Y; | |||||
if (point.Dot(u).Absolute() < hw && point.Dot(v).Absolute() < hh && countInsideAsZero) | |||||
return fixed::Zero(); | |||||
/* | |||||
* The maximum distance from a point to an edge of a square equals the greatest distance | |||||
* from the point to the a corner. Thus calculating all and taking the greatest. | |||||
*/ | |||||
return std::max(std::max( | |||||
(point + u.Multiply(hw) + v.Multiply(hh)).Length(), | |||||
(point + u.Multiply(hw) - v.Multiply(hh)).Length()), | |||||
std::max( | |||||
(point - u.Multiply(hw) + v.Multiply(hh)).Length(), | |||||
(point - u.Multiply(hw) - v.Multiply(hh)).Length())); | |||||
} | |||||
fixed Geometry::MaxDistanceSquareToSquare(const CFixedVector2D& relativePos, const CFixedVector2D& u1, const CFixedVector2D& v1, const CFixedVector2D& halfSize1, const CFixedVector2D& u2, const CFixedVector2D& v2, const CFixedVector2D& halfSize2) | |||||
{ | |||||
/* | |||||
* The maximum distance from an edge of a square to the edge of another square | |||||
* equals the greatest distance from the any of the 16 corner corner distances. | |||||
*/ | |||||
Not Done Inline Actionsindentation bb: indentation | |||||
fixed hw1 = halfSize1.X; | |||||
fixed hh1 = halfSize1.Y; | |||||
return std::max(std::max( | |||||
MaxDistanceToSquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | |||||
MaxDistanceToSquare(relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true)), | |||||
std::max(MaxDistanceToSquare(relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | |||||
MaxDistanceToSquare(relativePos - u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true))); | |||||
} | |||||
bool Geometry::TestRaySquare(const CFixedVector2D& a, const CFixedVector2D& b, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | bool Geometry::TestRaySquare(const CFixedVector2D& a, const CFixedVector2D& b, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | ||||
{ | { | ||||
/* | /* | ||||
* We only consider collisions to be when the ray goes from outside to inside the shape (and possibly out again). | * We only consider collisions to be when the ray goes from outside to inside the shape (and possibly out again). | ||||
* Various cases to consider: | * Various cases to consider: | ||||
* 'a' inside, 'b' inside -> no collision | * 'a' inside, 'b' inside -> no collision | ||||
* 'a' inside, 'b' outside -> no collision | * 'a' inside, 'b' outside -> no collision | ||||
* 'a' outside, 'b' inside -> collision | * 'a' outside, 'b' inside -> collision | ||||
▲ Show 20 Lines • Show All 163 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
Unless they're overlapping in a weird way (two rectangles in a cross), but that's unlikely to happen.