我正在开发一个用于与SFML一起使用的c ++简单碰撞引擎。我查看了一些教程并得出结论,SAT对我的计划来说已经足够了,并开始实施。它似乎部分起作用。在测试它时,外部最短路径的矢量有时似乎是正确的。 Here's an image showing all outcomes on two polygons
这是我的功能,是碰撞检测的一部分。
Range::Range(float mi, float ma) :
min(mi), max(ma) {
}
Range Range::overlap(Range other) {
Range r;
r.min = min > other.min ? min : other.min;
r.max = max < other.max ? max : other.max;
return r;
}
Range CollisionShape::project(sf::Vector2f axis) {
float d = dot(_vertices_t[0], axis);
Range r(d, d);
for (unsigned i = 0; i < _num_vertices; i++) {
d = dot(_vertices_t[i], axis);
r.min = d < r.min ? d : r.min;
r.max = d > r.max ? d : r.max;
}
return r;
}
sf::Vector2f CollisionShape::sat(CollisionShape& other, bool own) {
sf::Vector2f ret;
bool first = true;
// Separating Axis Theorem
unsigned num = own ? _num_vertices : other._num_vertices;
sf::Vector2f* vertices = own ? _vertices_t : other._vertices_t;
for (unsigned i = 0; i < num; i++) {
sf::Vector2f v = normalize(vertices[(i + 1) % num] - vertices[i]);
sf::Vector2f n(v.y, -v.x);
Range r1 = project(n);
Range r2 = other.project(n);
if (r1.max < r2.min || r1.min > r2.max) {
return sf::Vector2f(0, 0);
}
Range overlap = r1.overlap(r2);
if (first || (overlap.max - overlap.min) < length(ret)) {
ret = -n * (overlap.max - overlap.min);
first = false;
}
}
return ret;
}
sf::Vector2f CollisionShape::collision(CollisionShape& other) {
// Test shape's potential separating axes
sf::Vector2f ret1 = sat(other, true);
if (ret1 == sf::Vector2f(0, 0)) {
return ret1;
}
// Test other shape's potential separating axes
sf::Vector2f ret2 = sat(other, false);
if (ret2 == sf::Vector2f(0, 0)) {
return ret2;
}
return (length(ret1) < length(ret2) ? ret1 : ret2);
}
我无法确定问题出在哪里。 大编辑:我有点看到连接。如果它们沿着x或y轴(对于一个元素包含0),似乎向量是错误的。仍然不知道这是怎么发生的。