平面物体碰撞检测
程序员文章站
2022-03-13 15:26:53
...
闲来没事,突然想起了,最初学Android时,老师教过最简单矩形碰撞和精灵切割这些简单的算法,当时还说Android主要分两个方向,一个是做应用,一个是做游戏,现在想来,那夕阳下的奔跑,那是我逝去的青春…
虽然现在主要是做Android应用开发,但是闲着没事,也就突然想着,把这简单的平面物体碰撞检测算法试着分析分析,并整理写了下。
代码如下:
/**
* @author Jenly
* @date 2016-6-2
*/
public class CollsionUtils {
/**
* 点与矩形碰撞
* @param x1
* 点的x坐标
* @param y1
* 点的y坐标
* @param x2
* 矩形的x坐标
* @param y2
* 矩形的y坐标
* @param w
* 矩形的宽度
* @param h
* 矩形的高度
* @return
*/
public static boolean isCollsionWithPointAndRect(int x1,int y1,int x2,int y2,int w,int h){
//如果点在矩形的左边或在矩形的右边或在矩形的上边或在矩形的下边 则表示点与矩形没有发生碰撞,反之则表示发生碰撞
if(x1<x2 || x1>x2+w || y1<y2 || y1>y2+h)
return false;
return true;
}
/**
* 点与圆碰撞
* @param x1
* 点的x坐标
* @param y1
* .
* 点的y坐标
* @param x2
* 圆心的x坐标
* @param y2
* 圆心的y坐标
* @param r
* 圆的半径
* @return
*/
public static boolean isCollsionWithPointAndCircle(int x1,int y1,int x2,int y2,int r){
//根据点和圆心画直角坐标系,算出点和圆心的直线距离(即直角三角形的斜线),如果点和圆心的距离大于圆的半径则认为点与圆没有发生碰撞,反之则发生了碰撞
if(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2))>r)
return false;
return true;
}
/**
* 矩形碰撞
* @param x1
* 矩形1的x坐标
* @param y1
* 矩形1的y坐标
* @param w1
* 矩形1的宽度
* @param h1
* 矩形1的高度
* @param x2
* 矩形2的x坐标
* @param y2
* 矩形2的y坐标
* @param w2
* 矩形2的宽度
* @param h2
* 矩形2的高度
* @return
*/
public static boolean isCollsionWithRect(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2){
//如果矩形1在矩形2的左边或在矩形的右边或在矩形的上边或在矩形的下边 则表示点与矩形没有发生碰撞,反之则表示发生了碰撞
if(x1+w1<x2 || x1>x2+w2 || y1+h1<y2 || y1>y2+h2)
return false;
return true;
}
/**
* 矩形与圆碰撞
* @param x1
* 矩形的x坐标
* @param y1
* 矩形的y坐标
* @param w
* 矩形的宽度
* @param h
* 矩形的高度
* @param x2
* 圆心的x坐标
* @param y2
* 圆心的y坐标
* @param r
* 圆的半径
* @return
*/
public static boolean isCollsionWithRectAndCircle(int x1,int y1,int w,int h,int x2,int y2,int r){
//把圆看成一个矩形,判断矩形碰撞,如果碰撞了,则矩形与圆也一定彭碰撞了,反之则判断矩形的四个角是否与圆碰撞
if(isCollsionWithRect(x1, y1, w, h, x2-r, y2-r, 2*r, 2*r))
return true;
//矩形的左上角与与圆碰撞了
if(isCollsionWithPointAndCircle(x1, y1, x2, y2, r))
return true;
//矩形的右上角与与圆碰撞了
if(isCollsionWithPointAndCircle(x1+w, y1, x2, y2, r))
return true;
//矩形的左下角与与圆碰撞了
if(isCollsionWithPointAndCircle(x1, y1+h, x2, y2, r))
return true;
//矩形的右下角与与圆碰撞了
if(isCollsionWithPointAndCircle(x1+w, y1+h, x2, y2, r))
return true;
//以上条件都不满足则表示没有发生碰撞
return false;
}
/**
* 圆形碰撞
* @param x1
* 圆1的圆心x坐标
* @param y1
* 圆1的圆心y坐标
* @param r1
* 圆1的半径
* @param x2
* 圆2的圆心x坐标
* @param y2
* 圆2的圆心y坐标
* @param r2
* 圆2的半径
* @return
*/
public static boolean isCollsionWithCircle(int x1,int y1,int r1,int x2,int y2,int r2){
//根据两个圆心的坐标画直角坐标系,算出两个圆心的直线距离(即直角三角形的斜线),两个圆心的直线距离大于两个圆的的半径距离则表示没有发生碰撞,反之则发生了碰撞
if(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2))> r1+r2)
return false;
return true;
}
}