```package com.cocos2dj.module.base2d.framework.collision;

import com.cocos2dj.module.base2d.framework.common.MathUtils;
import com.cocos2dj.module.base2d.framework.common.V2;

/**碰撞检测算法<p>
*
* 修改了FloatPair的实现从new改为了单例模式 ,改变了变量的获取方法。
* #data:
* 		2012.11.23 改变了AABB的检测代码采用本地坐标检测<br>
* 入口的方法只有Intersect 其余方法均为辅助<p>
*
* 新增了形状圆 <p>
* @author xujun
public final class CollideAlgorithms {

/**最大边的数量*/
private static final int MAX_VERTICES = 12;

private static final Vector2[] poolVector2Array;
private static final Vector2[] poolVector2Interval;

private static FloatPair pair = null;
/**轴X单位向量 使用后应初始化*/
public static final Vector2 axisX = new Vector2(1,0);
/**轴Y单位向量 使用后应初始化*/
public static final Vector2 axisY = new Vector2(0,1);

//pools 基本都用在圆与多边形的测试上
private static final Vector2 pool1 = new Vector2();
private static final Vector2 pool2 = new Vector2();
private static final Vector2 pool3 = new Vector2();
private static final Vector2 pool4 = new Vector2();
private static final Vector2 pool5 = new Vector2();

static
{
poolVector2Array = new Vector2[MAX_VERTICES];
for(int i = 0; i < MAX_VERTICES; ++i){
poolVector2Array[i] = new Vector2();
}
poolVector2Interval = new Vector2[MAX_VERTICES];
for(int i = 0; i < MAX_VERTICES; ++i){
poolVector2Interval[i] = new Vector2();
}
}

//	private static final Vector2 pool2=new Vector2();
//private static final Vector2 pool3=new Vector2();

//TODO 多边形之间的检测相关方法
/**计算多边形p在axis轴上的投影并返回最大最小值
* 注意axis为单位向量
* @param axis
* @param p
* @param position 形状p的位置
* @return FloatPair */
public static final FloatPair CalculateInterval(final Vector2 axis, final Polygon p,
final Vector2 position) {

final Vector2[] points = p.getPoints();
//		a.x * b.x + a.y * b.y
//		float d = Vector2.dot(axis, points[0]);
float d = axis.x * (points[0].x + position.x) + axis.y * (points[0].y + position.y);
float min = d;
float max = d;

final int length = points.length;
for(int i = 0; i < length; i++){
//	    	d=Vector2.dot(axis, points[i]);
d = axis.x * (points[i].x + position.x) + axis.y * (points[i].y + position.y);
if(d < min) {
min = d;
} else if(d > max) {
max = d;
}
}
return FloatPair.getFloatPair(min, max);
}

/**测试在Axis轴上的A、B是否分离<br>
* @param Axis
* @param A
* @param B
* @param positionA A的位置
* @param positionB B的位置
* @return <code>true</code> 分离
* <code>false</code> 未分离*/
public static final boolean axisSeparatePolygons(final Vector2 Axis, final Polygon A, final Polygon B,
final Vector2 positionA, final Vector2 positionB) {
float mina, maxa;
float minb, maxb;

pair=CalculateInterval(Axis, A, positionA);
mina=pair.min;
maxa=pair.max;

pair=CalculateInterval(Axis, B, positionB);
minb=pair.min;
maxb=pair.max;

if (mina > maxb || minb > maxa)
return true;
// find the interval overlap
//		float d0 = maxa - minb;
//		float d1 = maxb - mina;
//		float depth = (d0 < d1)? d0 : d1;
//修剪轴
// convert the separation axis into a push vector (re-normalise
// the axis and multiply by interval overlap)
//		float axisLengthSquared = Vector2.dot(Axis, Axis);
//		Axis.mulThis(depth / axisLengthSquared);
return false;
}

/**检测两个多边形的相交
* @param A
* @param B
* @return <code>true</code> 相交
* <code>false</code> 不相交*/
public static final boolean Intersect(final Polygon A, final Polygon B,
final Vector2 positionA, final Vector2 positionB){
for(int i=A.getPoints().length-1; i>=0;i--){
pool1.set(-A.getPoints()[i].y, A.getPoints()[i].x);
if (axisSeparatePolygons(pool1, A, B, positionA, positionB))
return false;
}

for(int i=B.getPoints().length-1; i>=0;i--){
pool1.set(-B.getPoints()[i].y, B.getPoints()[i].x);
if (axisSeparatePolygons(pool1, A, B, positionA, positionB))
return false;
}
return true;
}

/**测试在Axis轴上的A、B是否分离  并 将轴用于MTD测试
* @param Axis
* @param A
* @param B
* @param positionA
* @param positionB
* @return <code>true</code> 分离
* <code>false</code> 未分离 */
public static final boolean axisSeparatePolygonsMTD(final Vector2 Axis, final Polygon A, final Polygon B,
final Vector2 positionA, final Vector2 positionB) {
pair=CalculateInterval(Axis, A, positionA);
final float mina=pair.min;
final float maxa=pair.max;

pair=CalculateInterval(Axis, B, positionB);
final float minb=pair.min;
final float maxb=pair.max;

if (mina > maxb || minb > maxa)
return true;

// find the interval overlap
final float d0 = maxa - minb;
final float d1 = maxb - mina;
final float depth = (d0 < d1)? d0 : d1;

// convert the separation axis into a push vector (re-normalise
// the axis and multiply by interval overlap)
float axisLengthSquared = V2.dot(Axis, Axis);
Axis.scl(depth / axisLengthSquared);
return false;
}

/** 搜寻MTD<br>
* 从所给推进向量中求出MTD
* @param pushVectors
* @param numVectors
* @return MTD*/
public static final Vector2 FindMTD(final Vector2[] pushVectors, final int numVectors) {
Vector2 MTD = pushVectors[0];
float mind2 = V2.dot(pushVectors[0],pushVectors[0]);
for(int i=1; i<numVectors; ++i) {
float d2 = V2.dot(pushVectors[i], pushVectors[i]);
if (d2 < mind2) {
mind2 = d2;
MTD = pushVectors[i];
}
}
return MTD;
}

/**相交测试并求出MTD向量   结果存放在参数MTD中
* 沿MTD向量就可以讲物体分开
* @param A
* @param B
* @param MTD
* @return <code>true</code> 相交
* <code>false</code> 不相交 */
public static final boolean Intersect(final Polygon A, final Polygon B,
final Vector2 positionA, final Vector2 positionB, final Vector2 MTD) {
Vector2[] axis=poolVector2Array;
// max of 10 vertices per polygon
Vector2 tempE=pool1;
Vector2 tempN=null;
final Vector2[] pointsA=A.getPoints();
final Vector2[] pointsB=B.getPoints();

int numAxis = 0;

//用这个不用单独求0的情况
for(int j=pointsA.length-1, i=0; i<pointsA.length;
j=i, ++i) {
tempE.set(pointsA[i].x-pointsA[j].x,pointsA[i].y-pointsA[j].y);
tempN=axis[numAxis++].set(-tempE.y, tempE.x);
if (axisSeparatePolygonsMTD(tempN, A, B, positionA, positionB))
return false;
}

for(int j=pointsB.length-1, i=0; i<pointsB.length;
j=i, ++i) {
tempE.set(pointsB[i].x-pointsB[j].x,pointsB[i].y-pointsB[j].y);
tempN=axis[numAxis++].set(-tempE.y, tempE.x);
if (axisSeparatePolygonsMTD(tempN, A, B, positionA, positionB))
return false;
}

//从所有的分离向量中查找最近的作为MTD
MTD.set(FindMTD(axis, numAxis));

// makes sure the push vector is pushing A away from B
//		Vector2 D = posiyionA.sub(B.getPosition());
pool1.set(positionA.x-positionB.x, positionA.y-positionB.y);
if (V2.dot(pool1, MTD)<0) {
V2.negate(MTD);
}

return true;
}

//TODO AABB形状之间检测相关方法
/**测试X轴向上的两个AABB是否分离
* <br>true为分离  axis为x轴的单位向量 必须传入(1,0)<br>
* <b>使用两个pool</b>
* @param Axis
* @param A
* @param B
* @param positionA
* @param positionB
* @return*/
public static final boolean axisSeparateAABBMTDX(final Vector2 axis,
final AABBShape A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB) {

final float mina=positionA.x+A.getPoints()[0].x;
final float maxa=positionA.x+A.getPoints()[2].x;
final float minb=positionB.x+B.getPoints()[0].x;
final float maxb=positionB.x+B.getPoints()[2].x;

if (mina > maxb || minb > maxa)
return true;

// find the interval overlap
final float d0 = maxa - minb;
final float d1 = maxb - mina;
final float depth = (d0 < d1)? d0 : d1;
// convert the separation axis into a push vector (re-normalise
// the axis and multiply by interval overlap)
axis.scl(depth);
return false;
}

/**测试Y轴向上的两个AABB是否分离
* <br>true为分离
* axis为x轴的单位向量 必须传入(0,1)
* @param Axis
* @param A
* @param B
* @param positionB
* @param positionA
* @return */
public static final boolean axisSeparateAABBMTDY(final Vector2 axis,final AABBShape A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB) {
final Vector2[] pointsA=A.getPoints();
final Vector2[] pointsB=B.getPoints();

final float mina=positionA.y+pointsA[0].y;
final float maxa=positionA.y+pointsA[2].y;
final float minb=positionB.y+pointsB[0].y;
final float maxb=positionB.y+pointsB[2].y;

if (mina > maxb || minb > maxa)
return true;

// find the interval overlap
final float d0 = maxa - minb;
final float d1 = maxb - mina;
final float depth = (d0 < d1)? d0 : d1;

// convert the separation axis into a push vector (re-normalise
// the axis and multiply by interval overlap)
axis.scl(depth);
return false;
}

/**相交测试并求出MTD向量
* 沿MTD向量就可以讲物体分开
* @param A				形状A
* @param B 			形状B
* @param positionA		形状A位置
* @param positionB		形状B位置
* @param MTD			MTD向量
* @return boolean true为相交false不相交*/
public static final boolean Intersect(final AABBShape A,final AABBShape B,
final Vector2 positionA, final Vector2 positionB, final Vector2 MTD){
//初始化轴向量
axisX.set(1, 0);
axisY.set(0, 1);

if(axisSeparateAABBMTDX(axisX, A, B, positionA, positionB)){
return false;
}
if(axisSeparateAABBMTDY(axisY, A, B, positionA, positionB)){
return false;
}

if(axisX.x>axisY.y){
MTD.set(axisY);
}else{
MTD.set(axisX);
}

//		System.out.println("MTD "+MTD);

// makes sure the push vector is pushing A away from B
//		pool1.set(positionA.x-positionB.x, positionA.y-positionB.y);
pool1.set(positionA.x + A.centerX - positionB.x - B.centerX, positionA.y + A.centerY - positionB.y - B.centerY);
if (V2.dot(pool1, MTD) < 0) {
V2.negate(MTD);
}
return true;
}

/**相交测试测试两个AABB之间的相交
* @param A				形状A
* @param B 			形状B
* @param positionA		形状A位置
* @param positionB		形状B位置
* @return */
public static final boolean Intersect(final AABBShape A,final AABBShape B,
final Vector2 positionA, final Vector2 positionB){
//向量A-向量B
//		final Vector2 v=A.getPosition().sub(B.getPosition());
//		final Vector2 v=positionA.sub(positionB);
pool1.set(positionA.x-positionB.x, positionA.y-positionB.y);
if (A.getPoints()[0].x+pool1.x > B.getPoints()[2].x|| B.getPoints()[0].x > pool1.x+A.getPoints()[2].x)
return false;
if (A.getPoints()[0].y+pool1.y> B.getPoints()[2].y || B.getPoints()[0].y > pool1.y+A.getPoints()[2].y)
return false;

return true;
}

//TODO AABB与多边形之间检测的相关方法
/**相交测试并求出MTD向量
* 沿MTD向量就可以讲物体分开
* @param A
* @param B
* @param positionA
* @param positionB
* @param MTD
* @return <code>true</code> 形状相交
* <code>false</code> 形状不相交*/
public static final boolean Intersect(final Polygon A,final AABBShape B,
final Vector2 positionA, final Vector2 positionB, final Vector2 MTD){
axisX.set(1, 0);
axisY.set(0, 1);

final Vector2[] pointsA=A.getPoints();
Vector2[] axis = poolVector2Array;
// max of 6 vertices per polygon
Vector2 tempE = pool1;
Vector2 tempN = null;
int numAxis = 0;

//用这个不用单独求0的情况
for(int j=pointsA.length-1, i=0; i<pointsA.length;
j=i, i++) {
//			tempE=A.getPoints()[i].sub(A.getPoints()[j]);
tempE.set(pointsA[i].x-pointsA[j].x, pointsA[i].y-pointsA[j].y);
tempN=axis[numAxis++].set(-tempE.y, tempE.x);
if (axisSeparatePolygonsMTD(tempN, A, B, positionA, positionB)) {
//				System.out.println("B = " + B);
return false;
}
}

//对x以及y轴的简化测试
if (axisSeparatePolygonsMTDX(axisX, A, B, positionA, positionB)) {
return false;
}
if (axisSeparatePolygonsMTDY(axisY, A, B, positionA, positionB)) {
return false;
}

axis[numAxis++].set(axisX);
axis[numAxis++].set(axisY);

//		for(int i = 0; i < numAxis; ++i) {
//			System.out.println("axis["+i+"] " + axis[i]);
//		}

//从所有的分离向量中查找最近的作为MTD
MTD.set(FindMTD(axis, numAxis));

//		System.out.println("MTD = " + MTD);

// makes sure the push vector is pushing A away from B
//		pool1.set(positionA.x - positionB.x, positionA.y - positionB.y);
pool1.set(positionA.x + A.centerX - positionB.x - B.centerX, positionA.y + A.centerY - positionB.y - B.centerY);
//		positionA.sub(positionB);
if (V2.dot(pool1, MTD)<0) {
V2.negate(MTD);
}
return true;
}

/**相交测试
* 多边形与AABB
* @param A
* @param B
* @param MTD
* @return  */
public static final boolean Intersect(final Polygon A,final AABBShape B,
final Vector2 positionA, final Vector2 positionB){
axisX.set(1,0);
axisY.set(0,1);
Vector2 tempE=null;
//用这个不用单独求0的情况
for(int j=A.getPoints().length-1, i=0; i<A.getPoints().length;
j=i, i++) {
tempE=A.getPoints()[i].sub(A.getPoints()[j]);
if (axisSeparatePolygonsMTD(new Vector2(-tempE.y, tempE.x), A, B, positionA, positionB))
return false;
}
if (axisSeparatePolygonsMTDX(axisX, A, B, positionA, positionB))
return false;
if (axisSeparatePolygonsMTDY(axisY, A, B, positionA, positionB))
return false;
return true;
}

/**测试在Axis轴上的A、B是否分离
* 用于MTD测试的方法
* <br>true为分离
* @param Axis
* @param A
* @param B
* @return */
public static final boolean axisSeparatePolygonsMTD(final Vector2 Axis, final Polygon A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB ) {
pair=CalculateInterval(Axis, A, positionA);
final float mina=pair.min;
final float maxa=pair.max;

pair=CalculateInterval(Axis, B, positionB);
final float minb=pair.min;
final float maxb=pair.max;

if (mina > maxb || minb > maxa)
return true;

// find the interval overlap
final float d0 = maxa - minb;
final float d1 = maxb - mina;
final float depth = (d0 < d1)? d0 : d1;

// convert the separation axis into a push vector (re-normalise
// the axis and multiply by interval overlap)
float axisLengthSquared = V2.dot(Axis, Axis);
Axis.scl(depth / axisLengthSquared);
return false;
}

/**测试在X轴上的A、B是否分离
* 用于MTD测试的方法
* Axis必须为(1,0)
* @param Axis
* @param A
* @param B
* @return <code>true</code> A与B分离
* <code>false</code> A与B重合 */
public static final boolean axisSeparatePolygonsMTDX(final Vector2 Axis, final Polygon A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB ) {
pair=CalculateInterval(Axis, A, positionA);
final float mina=pair.min;
final float maxa=pair.max;

final float minb=B.getPoints()[0].x+positionB.x;
final float maxb=B.getPoints()[2].x+positionB.x;

if (mina > maxb || minb > maxa)
return true;

// find the interval overlap
final float d0 = maxa - minb;
final float d1 = maxb - mina;
final float depth = (d0 < d1)? d0 : d1;

//直接求出即可
Axis.scl(depth);
return false;
}

/**测试在Y轴上的A、B是否分离
* 用于MTD测试的方法
* Axis必须为(0,1)
* <br>true为分离
* @param Axis
* @param A
* @param B
* @return <code>true</code> A与B分离
* <code>false</code> A与B重合*/
public static final boolean axisSeparatePolygonsMTDY(final Vector2 Axis, final Polygon A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB) {
pair=CalculateInterval(Axis, A, positionA);
final float mina=pair.min;
final float maxa=pair.max;

final float minb=B.getPoints()[0].y+positionB.y;
final float maxb=B.getPoints()[2].y+positionB.y;

if (mina > maxb || minb > maxa)
return true;

// find the interval overlap
final float d0 = maxa - minb;
final float d1 = maxb - mina;
final float depth = (d0 < d1)? d0 : d1;

Axis.scl(depth);
return false;
}

/**计算AABB p在axis轴上的投影并返回最大最小值
* 注意axis为单位向量
* @param axis
* @param p
* @param position
* @return <code>true</code> A与B分离
* <code>false</code> A与B重合*/
public static final FloatPair CalculateInterval(final Vector2 axis, final AABBShape p, final Vector2 position) {
final Vector2[] points = p.getPoints();
float d = axis.x * (points[0].x + position.x) + axis.y * (points[0].y + position.y);
float min = d;
float max = d;

for(int i = 0; i < 4; i++){
//	    	d=V2.dot(axis, temp[i]);
d = axis.x * (points[i].x + position.x) + axis.y * (points[i].y + position.y);
if(d < min) {
min = d;
} else if(d > max) {
max = d;
}
}
return FloatPair.getFloatPair(min, max);
}

/**测试在Axis轴上的A、B是否分离
* 用于MTD测试的方法
* <br>true为分离
* @param Axis
* @param A
* @param B
* @return */
public static final boolean axisSeparatePolygons(final Vector2 Axis, final Polygon A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB) {
pair = CalculateInterval(Axis, A, positionA);
final float mina = pair.min;
final float maxa = pair.max;

pair = CalculateInterval(Axis, B, positionB);
final float minb = pair.min;
final float maxb = pair.max;

if (mina > maxb || minb > maxa)
return true;
return false;
}

/**测试在X轴上的A、B是否分离
* 用于MTD测试的方法
* Axis必须为(1,0)
* @param Axis
* @param A
* @param B
* @param positionA
* @param positionB
* @return <code>true</code> 在x*/
public static final boolean axisSeparatePolygonsX(final Vector2 Axis, final Polygon A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB) {
pair=CalculateInterval(Axis, A, positionA);
final float mina=pair.min;
final float maxa=pair.max;

final float minb=B.getPoints()[0].x+positionB.x;
final float maxb=B.getPoints()[2].x+positionB.x;

if (mina > maxb || minb > maxa)
return true;
return false;
}

/**测试在Y轴上的A、B是否分离
* 用于MTD测试的方法
* Axis必须为(0,1)
* <br>true为分离
* @param Axis
* @param A
* @param B
* @param positionA
* @param positionB
* @return */
public static final boolean axisSeparatePolygonsY(final Vector2 Axis, final Polygon A, final AABBShape B,
final Vector2 positionA, final Vector2 positionB) {
pair=CalculateInterval(Axis, A, positionA);
final float mina=pair.min;
final float maxa=pair.max;

final float minb=B.getPoints()[0].y+positionB.y;
final float maxb=B.getPoints()[2].y+positionB.y;

if (mina > maxb || minb > maxa)
return true;
return false;
}

//TODO 关于圆与圆的计算
/**圆与圆的相交测试
* @param A
* @param B
* @param positionA
* @param positionB
* @return <code>true</code> 形状相交
* <code>false</code> 形状不相交 */
public static final boolean Intersect(final Circle A,final Circle B,
final Vector2 positionA,final Vector2 positionB){
pool1.set(positionA.x+A.circleCenter.x-positionB.x-B.circleCenter.x,
positionA.y+A.circleCenter.y-positionB.y-B.circleCenter.y);
final float dist2=V2.dot(pool1, pool1);
}

/**圆与圆的MTD相交测试
* @param A
* @param B
* @param positionA
* @param positionB
* @param MTD
* @return <code>true</code> 形状相交
* <code>false</code> 形状不相交 */
public static final boolean Intersect(final Circle A,final Circle B,
final Vector2 positionA,final Vector2 positionB,final Vector2 MTD){

//pool1为MTD的方向 pool2保存pool1的向量
pool1.set(positionA.x+A.circleCenter.x-positionB.x-B.circleCenter.x,
positionA.y+A.circleCenter.y-positionB.y-B.circleCenter.y);
pool2.set(pool1);

//求出向量的模并单位化向量
final float length = V2.normalize(pool1);

//计算两圆的刺入深度

if(depth >= 0){
MTD.set(pool1);
MTD.scl(depth);
// MTD方向应该是由positionB指向positionA
if (V2.dot(pool1, MTD)<0) {
V2.negate(MTD);
}
return true;
}

return false;
}

//TODO 关于圆与AABB的计算
/** 圆与AABB之间的相交测试
* @param A
* @param B
* @param positionA
* @param positionB
* @return <code>true</code> 形状相交
* <code>false</code> 形状不相交 */
public static final boolean Intersect(final Circle A,final AABBShape B,
final Vector2 positionA,final Vector2 positionB){
final Vector2[] points=B.getPoints();
float depth=0;
final float dx=positionA.x+A.circleCenter.x-positionB.x;
final float dy=positionA.y+A.circleCenter.y-positionB.y;

//判断A相对B的所处范围
if(dx>points[2].x){
if(dy>points[2].y)	pool1.set(points[2]);
else if(dy<points[1].y)	pool1.set(points[1]);
else{
if(depth>0) return true;
else return false;
}
}

else if(dx<points[3].x){
if(dy>points[3].y)	pool1.set(points[3]);
else if(dy<points[0].y)	pool1.set(points[0]);
else{
if(depth>0)return true;
else return false;
}
}

else{
if(dy>0){
if(depth>0) return true;
else return false;
}

else{
if(depth>0) return true;
else return false;
}
}

//最后的判断
final float tx=dx-pool1.x;final float ty=dy-pool1.y;
final float dist2=tx*tx+ty*ty;
return false;
}

/** 圆与AABB之间的MTD相交测试
* @param A
* @param B
* @param positionA
* @param positionB
* @param MTD
* @return <code>true</code> 形状相交
* <code>false</code> 形状不相交 */
public static final boolean Intersect(final Circle A,final AABBShape B,
final Vector2 positionA,final Vector2 positionB,final Vector2 MTD){
final Vector2[] points=B.getPoints();
float depth=0;
final float dx=positionA.x+A.circleCenter.x-positionB.x;
final float dy=positionA.y+A.circleCenter.y-positionB.y;

//		System.out.println("x "+dx+" y "+dy);
//		for(int i=0;i<4;i++){
//			System.out.println(i+" "+points[i]);
//		}
//判断A相对B的所处范围
if(dx>points[2].x){

if(dy>points[2].y) {
pool1.set(points[2]);
}
else if(dy<points[1].y)	{
pool1.set(points[1]);
}
else {
if(depth>0){
MTD.set(depth, 0);
return true;
}
else return false;
}
}

else if(dx<points[3].x){

if(dy>points[3].y)	pool1.set(points[3]);
else if(dy<points[0].y)	pool1.set(points[0]);
else{
if(depth>0){
MTD.set(-depth, 0);
return true;
}
else return false;
}

}

else{
if(dy>0){
if(depth>0){
MTD.set(0, depth);
return true;
}
else return false;
}

else{
if(depth>0){
MTD.set(0, -depth);
return true;
}
else return false;
}

}

//求出MTD向量
MTD.set(dx-pool1.x, dy-pool1.y);
float length= V2.normalize(MTD); //MTD.normalize();
if(depth>0){
MTD.scl(depth);
return true;
}

return false;
}

//TODO 关于圆与多边形的计算
/** 圆与多边形之间的相交测试
* @param A 圆
* @param B 多边形（逆时针）
* @param positionA
* @param positionB
* @return <code>true</code> 形状相交
* <code>false</code> 形状不相交 */
public static final boolean Intersect(final Circle A,final Polygon B,
final Vector2 positionA,final Vector2 positionB){
//其中pool1存放的是A相对于B的坐标
final Vector2[] points=B.getPoints();
//		pool1.set(positionA.x-positionB.x, positionA.y-positionB.y);
pool1.set(positionA.x+A.circleCenter.x-positionB.x,
positionA.y+A.circleCenter.y-positionB.y);

//判断positionB的所在区间
//这里决定采用一些ShapeAlgorithm的算法
int low=0;
int high=points.length;
final int length=high-1;

//找出positionA相对于多边形B的的所在侧
do{
int mid=(low+high)/2;
if(ShapeAlgorithms.TriangleIsCCW(points[0],points[mid],pool1))
low=mid;
else
high=mid;
}while(low+1<high);

Vector2 a,b,c;
final int index0=low-1<0?length:low-1;
final int index1=low;
final int index2=high%points.length;
final int index3=(high+1)%points.length;

a = pool2.set(points[index1].x-points[index0].x, points[index1].y-points[index0].y);
b = pool3.set(points[index2].x-points[index1].x, points[index2].y-points[index1].y);
c = pool4.set(points[index3].x-points[index2].x, points[index3].y-points[index2].y);

pool5.set(pool1.x-points[index1].x, pool1.y-points[index1].y);
final float s0 = V2.dot(a, pool5);
final float t0 = V2.dot(b, pool5);

if(s0>=0&&t0<=0){
//说明pool5为最近点
float dist2=V2.dot(pool5, pool5);
else return false;
}

pool5.set(pool1.x-points[index2].x, pool1.y-points[index2].y);
//		float s1 = Vector2.dot(a.negate(), pool5);
final float s1 = V2.dot(b, pool5);
final float t1 = V2.dot(c, pool5);

if(s1>=0&&t1<=0){
//说明pool5为最近点
float dist2=V2.dot(pool5, pool5);
else return false;
}

else if(t0 > 0 && s1 < 0){
pool5.set(pool1.x-points[index1].x, pool1.y-points[index1].y);

V2.negate(b);
//			b.nor();
float dist=MathUtils.abs(V2.cross(pool5, b));

if(depth>0) return true;
else return false;
}

else if(s0 < 0){
pool5.set(pool1.x-points[index0].x, pool1.y-points[index0].y);
V2.normalize(a);
float dist=MathUtils.abs(V2.cross(pool5, a));

if(depth>0) return true;
else return false;
}

else if(t1 > 0){
pool5.set(pool1.x-points[index2].x, pool1.y-points[index2].y);
V2.normalize(c);
float dist=MathUtils.abs(V2.cross(pool5, c));

if(depth>0) return true;
else return false;
}
return false;
}

/** 圆与多边形之间的MTD相交测试
* @param A 圆
* @param B 多边形（逆时针）
* @param positionA
* @param positionB
* @param MTD
* @return <code>true</code> 形状相交
* <code>false</code> 形状不相交 */
public static final boolean Intersect(final Circle A,final Polygon B,
final Vector2 positionA,final Vector2 positionB,final Vector2 MTD){
//其中pool1存放的是A相对于B的坐标
final Vector2[] points=B.getPoints();
//		pool1.set(positionA.x-positionB.x, positionA.y-positionB.y);
pool1.set(positionA.x+A.circleCenter.x-positionB.x,
positionA.y+A.circleCenter.y-positionB.y);
//判断positionB的所在区间
//这里决定采用一些ShapeAlgorithm的算法
int low=0;
int high=points.length;
final int length=high-1;

//找出positionA相对于多边形B的的所在侧
do{
int mid=(low+high)/2;
if(ShapeAlgorithms.TriangleIsCCW(points[0],points[mid],pool1))
low=mid;
else
high=mid;
}while(low+1<high);

Vector2 a,b,c;
final int index0=low-1<0?length:low-1;
final int index1=low;
final int index2=high%points.length;
final int index3=(high+1)%points.length;

a = pool2.set(points[index1].x-points[index0].x, points[index1].y-points[index0].y);
b = pool3.set(points[index2].x-points[index1].x, points[index2].y-points[index1].y);
c = pool4.set(points[index3].x-points[index2].x, points[index3].y-points[index2].y);

//		Vector2 temp=pool1.sub(points[0]);
pool5.set(pool1.x-points[index1].x, pool1.y-points[index1].y);
final float s0 = V2.dot(a, pool5);
final float t0 = V2.dot(b, pool5);

if(s0>=0&&t0<=0){
//说明pool5为最近点
float l= V2.normalize(pool5);

if(depth>0){
MTD.set(pool5);
MTD.scl(depth);
if(V2.dot(pool1, MTD)<0){
V2.negate(MTD);
}
return true;
}
else return false;
}

//		temp=p.sub(v[1]);
pool5.set(pool1.x-points[index2].x, pool1.y-points[index2].y);
//		float s1 = Vector2.dot(a.negate(), pool5);
final float s1 = V2.dot(b, pool5);
final float t1 = V2.dot(c, pool5);

if(s1>=0&&t1<=0){
//说明pool5为最近点
float l= V2.normalize(pool5);

if(depth>0){
MTD.set(pool5);
MTD.scl(depth);
if(V2.dot(pool1, MTD)<0){
V2.negate(MTD);
}
return true;
}
else return false;
}

else if(t0 > 0 && s1 < 0){
//return ClosetDistanceSquarePtSegment(p,v[low],v[high]);
pool5.set(pool1.x-points[index1].x, pool1.y-points[index1].y);
V2.normalize(b);
float dist=MathUtils.abs(V2.cross(pool5, b));
//			float dist=C2Math.sqrt(dist2);

if(depth>0){
MTD.set(-b.y,b.x);
MTD.scl(depth);
if(V2.dot(pool1, MTD)<0){
V2.negate(MTD);
}
return true;
}
else return false;
}

else if(s0 < 0){
//return ClosetDistanceSquarePtSegment(p,v[low-1],v[low]);
pool5.set(pool1.x-points[index0].x, pool1.y-points[index0].y);
V2.normalize(a);
float dist=MathUtils.abs(V2.cross(pool5, a));
//			float dist=C2Math.sqrt(dist2);

if(depth>0){
MTD.set(-a.y,a.x);
MTD.scl(depth);
if(V2.dot(pool1, MTD)<0){
V2.negate(MTD);
}
return true;
}
else return false;
}

else if(t1 > 0){
//return ClosetDistanceSquarePtSegment(p,v[high],v[high+1]);
pool5.set(pool1.x-points[index2].x, pool1.y-points[index2].y);
V2.normalize(c);
float dist=MathUtils.abs(V2.cross(pool5, c));
//			float dist=C2Math.sqrt(dist2);

if(depth>0){
MTD.set(-c.y,c.x);
MTD.scl(depth);
if(V2.dot(pool1, MTD)<0){
V2.negate(MTD);
}
return true;
}
else return false;
}

return false;
}
}

```