//returnthedistance
return((dx+dy)-(mn>>1)-(mn>>2)+(mn>>3));
}
两种算法测试:
用1000和10000组随机数据做测试,结果表明
approx_distance2D平均误差为1%,fastDistance2D平均误差为3%-3.5%,
2.2.2点到直线
基于上一小节两点间距离的快速近似算法,通过推导,可以得出点到直线的快速近似算法。
如下:
/**
*Calculatedistanceofapointtoaline.
*Pointis(x0,y0).
*Lineislinkedby(x1,y1)and(x2,y2).
*/
publicstaticintdistPointToLine(intx0,inty0,intx1,inty1,intx2,inty2)
{
//getthelineformula:
Ax+By+C=0
intA=y2-y1;
intB=x1-x2=-(x2-x1);
intC=x2*y1-x1*y2;
//thedistance:
abs(A*x0+B*y0+C)/sqrt(A*A+B*B):
参看下面推导
//iffastDistance2D(A,B)==0,……….
returnMath.abs(A*x0+B*y0+C)/fastDistance2D(A,B);
}
推导
直线方程是y=(A/B)*x+C/B
所以在点(x0,y0)出做向X轴的直线,那么和直线的交点就是
(x4,y4)=(x0,(A/B)*x0+C/B)
所以垂直距离是(y4–y0)*B/DistanceAB=((A/B)*x0+C/B-y0)*B/DistanceAB
=(A*x0-y0*B+C)/DistanceAB
2.3三角函数
快速计算sin和cos的方法
1.SplinterCellPT里面提供的一种算法
Sin(angle)=angle-angle*angle*angle/(6*100*100);
Cos(angle)=1*100-angle*angle/(2*100);
这儿的angle是以弧度为单位,由于J2ME不支持浮点运算,把Pi扩大了一百倍(314)。
该方法比较实用,也比较精确
2.ZengXiaoBing提供的一种算法
单位是角度,扩大了8100倍
publicfinalstaticintSIN=0;
publicfinalstaticintCOS=1;
publicstaticintsc(intop,intdir)
{
intsign=1;
//while(dir<0)dir+=360;
while(dir>360)dir-=360;
if(dir>=180)
{
dir-=180;
sign=-1;
}
if(dir>90)
{
dir=180-dir;
if(op==COS)
sign*=-1;
}
if(op==COS)
dir=90-dir;
//returnsign*SIN_VALUE[(dir+5)/10];
returnsign*(8100-(90-dir)*(90-dir));
//useparabolatosimulatesinecurve
}
原理是用抛物线来模拟正弦曲线。
注意:
PT版本的cos函数,在0-45度(0-157/2)内准确度是很高的,但在45-90度间,准确度极度下降(误差%6.7),而且当angle大于141后,会出现负数的情况。
所以,建议只在0-45度间使用,超过45度的,用sin(157–angle)求余弦,用cos(157–angle)求正弦。
2.4碰撞和裁剪
2.4.1点和矩形
点和矩形是否碰撞,只需判断该点位于矩形得内部区域就可以了。
staticpublicfinalintCS_TOP=0x01;
staticpublicfinalintCS_BOTTOM=0x02;
staticpublicfinalintCS_RIGHT=0x04;
staticpublicfinalintCS_LEFT=0x08;
publicstaticintCompOutcode(intx,inty,intxmin,intymin,intxmax,intymax)
{
intcode=0;
if(y>ymax)code|=CS_TOP;
if(yif(x>xmax)code|=CS_RIGHT;
if(xreturncode;
}
如果返回得code得值为0就可以判断点和矩形发生了碰撞。
2.4.2直线和矩形
判断直线(线段)和矩形相交的算法。
对于大多数游戏都没用,但如果允许任意角度的射线(比如子弹轨迹),那么它就很有用了。
这个算法的核心思想就是把坐标按照矩形分为九个小的区域,然后依据直线端点所在的区域分别进行计算,这样可以大大减少计算量。
/**