ajax传值到前台:求一个fortran关于小球碰撞的程序

来源:百度文库 编辑:高校问答 时间:2024/03/28 19:12:22
十个同样大小的刚性小球,在一个盒子中互相碰撞运动。初始位置和速度都是随机的,要求输出每次碰撞之后十个球的位置和速度,并且用VC的图像功能显示在屏幕上。
老板要求用fortran编写,我主要是一直找不到产生随机数的那个函数,还有怎样利用fortran输出的一系列位置坐标将小球显示在屏幕上

我以前做过这个程序最近也改写了代码,但还是有点乱,而且也没太好的实现(主要是误差的问题).
算法代码:
#define MY_FLOAT double

#include <math.h>

#define M_PI (MY_FLOAT)3.14159265358979323846
#define M_PI_2 (MY_FLOAT)1.57079632679489661923
//pi + pi/2
#define M_PI_PI_2 (MY_FLOAT)4.71238898038468985769
//pi*2
#define M_PI_M2 (MY_FLOAT)6.28318530717958647692
//min
#define M_F_MIN (MY_FLOAT)0.00001
//等于
#define M_EQUAL(a, b) (abs(a-b) < M_F_MIN)
//不等于
#define M_UNEQUAL(a, b) (abs(a-b) > M_F_MIN)

//================================================================
// 函数名称:GetAngle
// 功能 :获得矢量与Y轴的夹角
// 返回值 :返回矢量与Y轴的夹角(弧度)(顺时针)(三四象限为负)( -M_PI - M_PI )
// 参数说明:矢量的X和Y坐标
//================================================================
MY_FLOAT GetAngle(MY_FLOAT fx,MY_FLOAT fy)
{
return atan2( fx , fy );
}

//================================================================
// 函数名称:GetAngle
// 功能 :获得矢量与Y轴(正值)的夹角
// 返回值 :返回矢量与Y轴(正值)的夹角(弧度)(顺时针)(三四象限为正)( 0 - M_PI_M2 )
// 参数说明:矢量的X和Y坐标
//================================================================
MY_FLOAT GetAngleNoMinus(MY_FLOAT fx,MY_FLOAT fy)
{
double tangle = atan2( fx , fy );
return tangle < 0 ? M_PI_M2 + tangle : tangle;
}

//================================================================
// 函数名称:GetAngleB
// 功能 :获得矢量与矢量的夹角
// 返回值 :返回矢量1到矢量2的夹角(弧度)(顺时针)( 0 - M_PI_M2 )
// 参数说明:矢量1和2的X和Y坐标
//================================================================
MY_FLOAT GetAngleB(MY_FLOAT fx1,MY_FLOAT fy1,MY_FLOAT fx2,MY_FLOAT fy2)
{
MY_FLOAT angle = GetAngle( fx2 ,fy2 ) - GetAngle( fx1 ,fy1 );
return angle >= 0 ? angle : ( M_PI_M2 + angle );
}

//================================================================
// 函数名称:LAtoXY
// 功能: 矢量的长度和角度转换成坐标
// 返回值 :成功:TRUE,否则FALSE
// 参数说明:fx,fy:[out]返回矢量坐标
// flennth:[in]矢量长度
// fangle:[in]矢量角度
//================================================================
void LAtoXY(MY_FLOAT &fx,MY_FLOAT &fy,MY_FLOAT flength,MY_FLOAT fangle)
{
fx = flength * sin( fangle );
fy = flength * cos( fangle );
}

//================================================================
// 函数名称:XYtoLA
// 功能: 矢量的坐标转换成长度和角度
// 返回值 :成功:TRUE,否则FALSE
// 参数说明:fx,fy:[in]返回矢量坐标
// flennth:[out]矢量长度
// fangle:[out]矢量角度
//================================================================
void XYtoLA(MY_FLOAT &flength,MY_FLOAT &fangle,MY_FLOAT fx,MY_FLOAT fy)
{
flength = sqrt( fx*fx + fy*fy );
fangle = GetAngle( fx , fy );
}

//================================================================
// 函数名称:GetHeft
// 功能 :获得矢量的分量(两个互相垂直的矢量)
// 返回值 :TRUE为可以获得分量,FALSE为不可以
// 参数说明:fx1和fy1是矢量的坐标,
// fangle 为矢量与其中一分量的夹角,可以为负.
// 返回 fx1,fy1,fx2,fy2 为分量的坐标
// 分量 fx1,fy1 与矢量夹角为 fangle
// 分量 fx2,fy2 与矢量夹角为 M_PI_2 - fangle
//================================================================
BOOL GetHeft(MY_FLOAT &fx1,MY_FLOAT &fy1,MY_FLOAT &fx2,MY_FLOAT &fy2,MY_FLOAT fangle)
{
MY_FLOAT tlength,tangle;
MY_FLOAT tlength2,tangle2;
bool tbdeasil = true;
if( fangle < 0 )
{
if( fangle < -M_PI_2 )
{
if( fangle > -M_PI_PI_2 || fangle < -M_PI_M2 )
{
fx2 = 0;
fy2 = 0;
return FALSE;
}
else
{
fangle += M_PI_M2;
}
}
else
{
fangle += M_PI_2;
tbdeasil = false;
}
}
if( fangle > M_PI_2 )
{
if( fangle < M_PI_PI_2 || fangle > M_PI_M2 )
{
fx2 = 0;
fy2 = 0;
return FALSE;
}
else
{
fangle = M_PI_M2 - fangle;
tbdeasil = false;
}
}
if( M_EQUAL( fangle , 0 ) )
{
fx2 = 0;
fy2 = 0;
return TRUE;
}
XYtoLA( tlength , tangle , fx1 , fy1 );
if( tbdeasil )
{
tlength2 = tlength * cos( fangle );
tangle2 = tangle + fangle;
if( tangle2 > M_PI_M2 )
{
tangle2 -= M_PI_M2;
}
LAtoXY( fx1 , fy1 , tlength2 , tangle2 );

tlength2 = tlength * sin( fangle );
tangle2 = tangle2 - M_PI_2;
if( tangle2 < 0 )
{
tangle2 += M_PI_M2;
}
LAtoXY( fx2 , fy2 , tlength2 , tangle2 );
}
else
{
tlength2 = tlength * cos( fangle );
tangle2 = tangle - fangle;
if( tangle2 < 0 )
{
tangle2 += M_PI_M2;
}
LAtoXY( fx1 , fy1 , tlength2 , tangle2 );

tlength2 = tlength * sin( fangle );
tangle2 = tangle2 + M_PI_2;
if( tangle2 > M_PI_M2 )
{
tangle2 -= M_PI_M2;
}
LAtoXY( fx2 , fy2 , tlength2 , tangle2 );
}
return TRUE;
}

//================================================================
// 函数名称:GetIpe
// 功能 :根据两个分量获得矢量
// 返回值 :TRUE为可以获得矢量,FALSE为不可以
// 参数说明:fx1,fy1,fx2,fy2 为分量的坐标
// fx1和fy1是返回的矢量坐标,
//================================================================
void GetIpe(MY_FLOAT &fx1,MY_FLOAT &fy1,MY_FLOAT fx2,MY_FLOAT fy2)
{
fx1 += fx2;
fy1 += fy2;
}

//================================================================
// 函数名称:BallAfoul
// 功能: 计算两个质量相同的球碰撞后的运动,
// 根据两球的矢量,位置返回两球碰撞后的矢量.
// 返回值 :正常碰撞和未碰撞返回TRUE,异常碰撞返回FALSE
// 参数说明:x1,y1:第一个球的矢量,并返回碰撞后的矢量
// x2,y2:第二个球的矢量,并返回碰撞后的矢量
// xx1,xy1:第一个球的位置
// xx2,xy2:第二个球的位置
//================================================================
BOOL BallAfoul(int &x1,int &y1,int &x2,int &y2,int xx1,int xy1,int xx2,int xy2)
{
MY_FLOAT
fx1 = (MY_FLOAT)x1,
fy1 = (MY_FLOAT)y1,
fx2 = (MY_FLOAT)x2,
fy2 = (MY_FLOAT)y2;

MY_FLOAT tx1,ty1,tangle1,tangle2;//

MY_FLOAT
tfx1 = (MY_FLOAT)x1,
tfy1 = (MY_FLOAT)y1,
tfx2 = 0,
tfy2 = 0;

MY_FLOAT
ttfx1 = 0,
ttfy1 = 0,
ttfx2 = (MY_FLOAT)x2,
ttfy2 = (MY_FLOAT)y2;

bool
tboneball = true,
tbtwoball = true;
/////////////
tx1=MY_FLOAT(xx2-xx1);
ty1=MY_FLOAT(xy2-xy1);
tangle1 = GetAngleB( fx1 , fy1 , tx1 , ty1 );

if( !GetHeft( tfx1 , tfy1 , tfx2 ,tfy2 , tangle1 ) )
{
tboneball = false;
}

tx1=MY_FLOAT(xx1-xx2);
ty1=MY_FLOAT(xy1-xy2);
tangle2 = GetAngleB( fx2 , fy2 , tx1 , ty1 );

if( !GetHeft( ttfx2 ,ttfy2 , ttfx1 , ttfy1 , tangle2 ) )
{
tbtwoball = false;
}

if( (tboneball^tbtwoball) == true )
{
//异常碰撞检测,异常时返回
if( !tboneball )
{
tangle1 = tangle1 + M_PI;
if( tangle1 > M_PI_M2 )
{
tangle1 -= M_PI_M2;
}
GetHeft( tfx1 , tfy1 , tfx2 ,tfy2 , tangle1 );
if(sqrt( tfx1*tfx1 + tfy1*tfy1 ) >= sqrt( ttfx2*ttfx2 + ttfy2*ttfy2 ))
return FALSE;
tfx1 = (MY_FLOAT)x1;
tfy1 = (MY_FLOAT)y1;
tfx2 = 0;
tfy2 = 0;
}
else
{
tangle2 = tangle2 + M_PI;
if( tangle2 > M_PI_M2 )
{
tangle2 -= M_PI_M2;
}
GetHeft( ttfx2 ,ttfy2 , ttfx1 , ttfy1 , tangle2 );
if(sqrt( tfx1*tfx1 + tfy1*tfy1 ) <= sqrt( ttfx2*ttfx2 + ttfy2*ttfy2 ))
return FALSE;
ttfx1 = 0;
ttfy1 = 0;
ttfx2 = (MY_FLOAT)x2;
ttfy2 = (MY_FLOAT)y2;
}
}
else
{
//未发生碰撞
if( !tboneball )
{
return TRUE;
}
}

GetIpe( ttfx1 , ttfy1 , tfx1 , tfy1 );
GetIpe( ttfx2 , ttfy2 , tfx2 , tfy2 );

/////////////
x1=int(ttfx2+0.5);
y1=int(ttfy2+0.5);
x2=int(ttfx1+0.5);
y2=int(ttfy1+0.5);
return TRUE;
}