|
- 临界多边形碰撞检测通常指的是在二维或三维空间中判断两个或多个多边形是否相交的问题。这里提供一种基于二维临界多边形的简单相交检测算法——Separating Axis Theorem(SAT)算法的一个简化实现示例:
- ```cpp
- #include <iostream>
- #include <vector>
- #include <cmath>
- struct Vec2 {
- double x, y;
- Vec2(double x = 0, double y = 0) : x(x), y(y) {}
- Vec2 operator-(const Vec2& other) const {
- return Vec2(x - other.x, y - other.y);
- }
- double dot(const Vec2& other) const {
- return x * other.x + y * other.y;
- }
- Vec2 normalized() const {
- double len = std::sqrt(x * x + y * y);
- return Vec2(x / len, y / len);
- }
- };
- struct Polygon {
- std::vector<Vec2> vertices;
- };
- // 计算多边形的某条边的向量
- Vec2 getEdge(const Polygon& poly, size采用t i) {
- size采用t next采用i = (i + 1) % poly.vertices.size();
- return poly.vertices[next采用i] - poly.vertices[i];
- }
- // 计算多边形的投影
- stdx::optional<std::pair<double, double>> projectPolygon(const Polygon& poly, const Vec2& axis) {
- double minProj = axis.dot(poly.vertices[0]);
- double maxProj = minProj;
- for (size采用t i = 1; i < poly.vertices.size(); ++i) {
- double proj = axis.dot(poly.vertices[i]);
- minProj = std::min(minProj, proj);
- maxProj = std::max(maxProj, proj);
- }
- return std::make采用optional(std::make采用pair(minProj, maxProj));
- }
- // 判断两个多边形是否相交
- bool doPolygonsCollide(const Polygon& poly1, const Polygon& poly2) {
- for (size采用t i = 0; i < poly1.vertices.size(); ++i) {
- Vec2 edge = getEdge(poly1, i);
- auto proj1 = projectPolygon(poly1, edge.normalized());
- auto proj2 = projectPolygon(poly2, edge.normalized());
- if (!proj1 || !proj2) {
- continue; // 应该不会出现这种情况,除非多边形有问题
- }
- if (proj1->second < proj2->first || proj2->second < proj1->first) {
- return false; // 投影区间无重叠,说明沿着此轴不相交
- }
- }
- // 交换两多边形角色再做一次同样的循环,以防有些边在前一轮没覆盖到
- for (size采用t i = 0; i < poly2.vertices.size(); ++i) {
- Vec2 edge = getEdge(poly2, i);
- auto proj1 = projectPolygon(poly1, edge.normalized());
- auto proj2 = projectPolygon(poly2, edge.normalized());
- if (!proj1 || !proj2) {
- continue;
- }
- if (proj1->second < proj2->first || proj2->second < proj1->first) {
- return false;
- }
- }
- return true; // 所有分离轴测试均未发现无交集,认为两个多边形相交
- }
- int main() {
- // 初始化两个多边形
- Polygon poly1 = {/* 顶点列表 */};
- Polygon poly2 = {/* 顶点列表 */};
- if (doPolygonsCollide(poly1, poly2)) {
- std::cout << "The polygons are colliding.\n";
- } else {
- std::cout << "The polygons are not colliding.\n";
- }
- return 0;
- }
- ```
- 这个示例代码实现了SAT算法的基本原理,即检查两个多边形在所有可能的分离轴(即多边形的每一条边的法线)上是否都存在重叠的投影区间。如果存在至少一个分离轴使得两个多边形的投影区间没有重叠,则两个多边形不相交;否则,它们相交。
- 实际项目中,你可能需要进一步优化这个实现,例如只检查多边形对角线(潜在的分离轴)而不是所有的边,以及处理浮点数精度问题等。同时,这个例子假设了输入的多边形是凸多边形,如果是凹多边形,则需要额外处理。
复制代码 |
|