天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 53|回复: 0

凸多边形碰撞检测(C语言,未整理)

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
#include <stdbool.h>

#include <stdio.h>

#include <math.h>

#include <CoreGraphics/CoreGraphics.h>


//向量

typedef struct Vect
{

float x,y;

} Vect;


//多边形

typedef struct Polygon
{

int vertexCount;  //顶点数量

Vect *vertexes;  //顶点数组

} Polygon;


//圆形

typedef struct Circle
{

Vect o; // 圆心坐标

float r; //半径

} Circle;


//矩形

typedef struct Rectangle
{

float left, right, top, bottom;

} Rectangle;


//矩形构造器

static inline Rectangle rectMake(float left, float right, float top, float bottom)
{

Rectangle r = {left, right, top, bottom};

return r;

}


//向量构造器

static inline Vect vectMake(float x, float y)

{

Vect v = {x, y};

return v;

}


//向量点乘

static inline float vectDot(Vect v1, Vect v2)
{

return v1.x*v2.x + v1.y*v2.y;

}


//向量减法

static inline Vect vectSub(Vect v1, Vect v2)
{

return vectMake(v1.x - v2.x, v1.y - v2.y);

}


//向量长度

static inline float vectLength(Vect v)
{

return sqrt(v.x*v.x + v.y*v.y);

}



//向量的垂直向量

static inline Vect vectPerp(Vect v)
{

return vectMake(-v.y, v.x);

}


//两点距离的平方

static inline float disSquare(Vect p1, Vect p2)

{

return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);

}



bool circleCollision(Circle c1, Circle c2);





bool polygonCollision(Polygon p1, Polygon p2);



bool polygonCircleCollision(Polygon p, Circle c);



bool rectangleCircleCollision(Rectangle rect, Circle circle);







///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////





#include"SeparatingAxisTheorem.h"

static inline void projectPolygon(Vect axis, Polygon polygon, float* min, float* max)
{
float d = vectDot(axis, polygon.vertexes[0]);


*min = d;


*max = d;


for (int i = 0; i < polygon.vertexCount; i++)
{
d = vectDot(axis, polygon.vertexes[i]);
       if (d < *min)
{
   *min = d;
       }
else
{
  if (d > *max)
  {
   *max = d;
               }
  }
}
}


static inline void projectCircle(Vect axis, Circle circle, float* min, float* max)
{
float d = vectDot(axis, circle.o);


float axisLength = vectLength(axis);


*min = d - (circle.r * axisLength);


*max = d + (circle.r * axisLength);


}

static inline float intervalDistance(float minA, float maxA, float minB, float maxB)
{
return (minA < minB) ? (minB - maxA) : (minA - maxB);


}

bool polygonCollision(Polygon a, Polygon b)
{
Vect edge, axis;
float minA = 0, maxA = 0, minB = 0, maxB = 0;
for (int i = 0, j=a.vertexCount-1; i < a.vertexCount + b.vertexCount; j=i, i++)
{
//通过顶点取得每个边
if (i < a.vertexCount)
  {
   edge = vectSub(a.vertexes[i], a.vertexes[j]);
  

}
  else
  {
   edge = vectSub(b.vertexes[i-a.vertexCount], b.vertexes[j-a.vertexCount]);
  

}
  
  axis = vectPerp(edge); //向量的垂直向量
  
//以边的垂线为坐标轴进行投影,取得投影线段[min, max]
  projectPolygon(axis, a, &minA, &maxA);
  projectPolygon(axis, b, &minB, &maxB);
//检查两个投影的距离,如果两投影没有重合部分,那么可以判定这两个多边形没有碰撞
if (intervalDistance(minA, maxA, minB, maxB) > 0)
{
return false;
  
}
}
return true;
}

bool polygonCircleCollision(Polygon p, Circle c)
{
Vect edge, axis;
float minP = 0, maxP = 0, minC = 0, maxC = 0;
for(int i = 0, j=p.vertexCount-1; i < p.vertexCount; j=i, i++)
  {
       edge = vectSub(p.vertexes[i], p.vertexes[j]);
  axis = vectPerp(edge); // perpendicular to edge     
  
//以边的垂线为坐标轴进行投影,取得投影线段[min, max]
projectPolygon(axis, p, &minP, &maxP);
projectCircle(axis, c, &minC, &maxC);  
//printf("%.2f\n", intervalDistance(minP, maxP, minC, maxC));  
//检查两个投影的距离,如果两投影没有重合部分,那么可以判定这两个图形没有碰撞
if (intervalDistance(minP, maxP, minC, maxC) > 0)
{
   return false;
}
}
for(int i = 0; i < p.vertexCount; i++)
{
  axis = vectSub(c.o, p.vertexes[i]);  
projectPolygon(axis, p, &minP, &maxP);
projectCircle(axis, c, &minC, &maxC);
  
//printf("%.2f\n", intervalDistance(minP, maxP, minC, maxC));
  
  

if (intervalDistance(minP, maxP, minC, maxC) > 0)
  {
   return false;
}
}

return true;


}

bool circleCollision(Circle c1, Circle c2)
{
float dis = (c1.o.x - c2.o.x) * (c1.o.x - c2.o.x) +  (c1.o.y - c2.o.y) * (c1.o.y - c2.o.y);

if (dis > (c1.r + c2.r) * (c1.r + c2.r))
{
  return false;
}
else
{
  return true;

}
}


bool rectangleCircleCollision(Rectangle rect, Circle circle)
{
if (circle.o.x > rect.left - circle.r
               && circle.o.x < rect.right + circle.r
  && circle.o.y > rect.bottom - circle.r
  && circle.o.y < rect.top + circle.r)
{
  //左上角
if(circle.o.x < rect.left && circle.o.y > rect.top)
{
float dis = disSquare(vectMake(rect.left, rect.top), circle.o);
   

if( dis > circle.r * circle.r )
{
    return false;   
       }
}
  if(circle.o.x > rect.right && circle.o.y > rect.top)
  {
   float dis = disSquare(vectMake(rect.right, rect.top), circle.o);   
                       if( dis > circle.r * circle.r )
   {
    return false;   
}
}
  
if(circle.o.x < rect.left && circle.o.y < rect.bottom)
{
float dis = disSquare(vectMake(rect.left, rect.bottom), circle.o);
if( dis > circle.r * circle.r )
{
return false;
}
  }
  
if(circle.o.x > rect.right && circle.o.y < rect.bottom)
  {
   float dis = disSquare(vectMake(rect.right, rect.bottom), circle.o);
   

if( dis > circle.r * circle.r )
{
    return false;   
}
}
  return true;
}
return false;
}


//float vectorLength(const Vector& a)
//{
//    float length_squared = a.x*a.x + a.y*a.y;
//    return sqrt(length_squared);
//}
//
//// project polygon along an axis, and find it's dimensions.
//void polygonInterval(const Vector& axis, const Vector* a, int anum, float& min, float& max)
//{
//    min = max = vectorDot(a[0], axis);
//    for(int i = 1; i < anum; i ++)
//    {
//       float d = vectorDot(a[i], axis);;
//       if(d < min) min = d;
//       else if (d > max) max = d;
//    }
//}
//
//// project slphere along an axis, and find it's dimensions.
//void sphereInterval(const Vector& axis, const Vector& c, float r, float& min, float& max)
//{
//    float length = vectorLength(axis);
//    float cn = vectorDot(axis, c);
//    min = cn - (r * length);
//    max = cn + (r * length);
//}
//
//bool collidePolygonPolygonAxis(const Vector& axis, const Vector* a, int anum, const Vector* b, int bnum)
//{
//    float mina, maxa;
//    float minb, maxb;
//
//   polygonInterval(axis, a, anum, mina, maxa);
//   polygonInterval(axis, b, bnum, minb, maxb);
//
//    return (mina <= maxb && minb <= maxa);
//}
//
//bool collidePolygonPolygon(const Vector* a, int anum, const Vector* b, int bnum)
//{
//    for(int i = 0, j=anum-1; i < anum; j=i, i++)
//    {
//       Vector edge = vectorSub(a[i], a[j]);
//       Vector axis = vectorPerp(edge); // perpendicular to edge     
//  
//       if(!collidePolygonPolygonAxis(axis, a, anum, b, bnum))
//           return false;
//    }
//
//    for(int i = 0, j=bnum-1; i < bnum; j=i, i++)
//    {
//       Vector edge = vectorSub(b[i], b[j]);
//       Vector axis = vectorPerp(edge); // perpendicular to edge     
//  
//       if(!collidePolygonPolygonAxis(axis, a, anum, b, bnum))
//           return false;
//    }
//    return true;
//}
//
//bool collidePolygonSphereAxis(const Vector& axis, const Vector* a, int anum, const Vector& c, float r)
//{
//    float mina, maxa;
//    float minb, maxb;
//
//   polygonInterval(axis, a, anum, mina, maxa);
// sphereInterval(axis, c, r, minb, maxb);
//
//    return (mina <= maxb && minb <= maxa);
//}
//
//bool collidePolygonSphere(const Vector* a, int anum, const Vector& c, float r)
//{
//    for(int i = 0, j=anum-1; i < anum; j=i, i++)
//    {
//       Vector edge = vectorSub(a[i], a[j]);
//       Vector axis = vectorPerp(edge); // perpendicular to edge     
//  
//       if(!collidePolygonSphereAxis(axis, a, anum, c, r))
//           return false;
//    }
//
//    for(int i = 0; i < anum; i++)
//    {
//       Vector axis = vectorSub(c, a[i]);
//  
//       if(!collidePolygonSphereAxis(axis, a, anum, c, r))
//           return false;
//    }
//    return true;
//}

 

 

 

 

凸多边形碰撞检测(C语言,未整理)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 09:30 , Processed in 0.122725 second(s), 24 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表