小球移动轨迹渐变 android,利用C4droid绘制小球斜抛运动轨迹(考虑空气阻力)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

我把源代码分享出来,欢迎有兴趣的朋友下载测试,修改优化。

/***********************************************************************

此程序是考虑空气阻力条件下弹弓抛射8mm钢珠飞行轨迹的C++程序。

用到的公式:空气阻力的公式:F=(1/2)CρSV^2

计算.式中:C为空气阻力系数;ρ为空气密度;S物体迎风面积;V为物体与空气的相对

运动速度.但是C是空气阻力系数。

一些物体的风阻:垂直平面体风阻系数大约1.0 球体风阻系数大约0.5 一般轿车

风阻系数0.28-0.4 好些的跑车在0.25 赛车可以达到0.15 飞禽在0.1-0.2 飞机达到0.08

目前雨滴的风阻系数最小 在0.05左右。

作者:哈笛 时间:2019年10月19日

************************************************************************/

#include

#include

#include "SDL2/SDL.h"

#include

#include #define G 9.8

#define Pi 3.14159265359SDL_Window *win=NULL;

SDL_Renderer *render=NULL;

int main()

{

int i,j,k,k1; //for循环用的变量

float s,v,vt,vx,vy,theta_jd,theta_hd,F,Fy,C,P,S,Sy,Sy0,a,ay,m,T,T1,T2,tb,SS,ss,wc;

//v是钢珠的初速度,vt是钢珠水平方向的即时速度,vx,vy是钢珠水平、垂直方向的即时速度,theta_jd是射出角的角度表示,theta_jd是射出角的弧度表示,F是水平方向的空气阻力,

//Fy是垂直方向的空气阻力,C是钢珠的空气阻力系数,P是空气密度,S是小球的迎风面积,Sy是小球垂直方向的位移,Sy0是钢珠在单位时间tb内的垂直方向的位移,

//a是钢珠水平方向的加速度,ay是钢珠在垂直方向的加速度,m是钢珠的质量,T是钢珠总的飞行时间,T1是钢珠上升时间,T2是钢珠的下降时间,tb是单位时间,

//SS是钢珠水平方向的位移,ss是钢珠在单位时间tb内水平方向的位移,wc是理想瞄准位置与弹着点的偏差距离。

float x[1000],y[1000]; //用来标记单位时间钢珠水平、垂直方向位置的数组

FILE *fp; /*文件指针*/

int len; /*行字符个数*/

v=90; //钢珠射出的初速度

C=0.5; //钢珠的风阻系数

P=1.2; //空气密度

S=Pi*0.008*0.008; //钢珠的迎风面积

m=5.29*0.001; //钢珠的质量

/*for(theta_jd=1;theta_jd<=45;theta_jd++)

{

theta_hd=(Pi*theta_jd)/180;

s=(v*v*sin(2*theta_hd))/G;

printf("theta=%d s=%f ",theta_jd,s);

if(theta_jd%5==0) printf("\n");

}*/

theta_jd=37; //钢珠的射出角度

theta_hd=(Pi*theta_jd)/180; //射出角度的弧度制表示

printf("\n");

vy=v*sin(theta_hd); //钢珠在垂直方向的初速度

Fy=C*P*S*vy*vy/2; //钢珠在垂直方向的空气阻力

ay=-(Fy/m+G); //钢珠在垂直方向的加速度(上升阶段)

tb=0.01; //单位时间,0.01秒,用于将钢珠的飞行等分为若干小段,在每小段内钢珠为匀加速运动,该参数可以控制精度

T1=0; //上升阶段的飞行时间

T2=0; //下降阶段的飞行时间

Sy=0; //垂直方向的位移

i=0; //用于计算在上升阶段经历了少个单位时间,也用于垂直方向的坐标计算

while(vy>0) //此循环用于处理垂直向上运动,每个单位时间计算各项参数,结束条件为垂直方向速度小于等于0

{

vy=vy+ay*tb; //利用加速度、速度公式计算单位时间垂直方向的即时速度

Sy0=vy*tb+ay*tb*tb/2; //利用加速度、速度、位移公式计算单位时间垂直方向的位移

Sy+=Sy0; //对垂直方向的位移进行累加

Fy=C*P*S*vy*vy/2; //重新计算垂直方向的即时空气阻力

ay=-(Fy/m+G); //重新计算垂直方向的即时加速度

T1+=tb; //累加垂直方向的位移

y[i]=Sy; //将垂直方向的坐标存入数组y[i],数组的下标是时间单位,内容是单位时间垂直方向的位移

i++; //对数组下标进行累加,同时对用掉的单位时间进行计数

}

vy=0; //垂直方向的速度归零,准备处理垂直向下运动

Fy=C*P*S*vy*vy/2; //垂直方向的空气阻力,初值为零

ay=-Fy/m+G; //垂直方向的加速度

while(Sy>0) //此循环用于处理垂直向下运动,每个单位时间计算各项参数,结束条件为垂直向下的位移等于垂直向上的位移

{

vy=vy+ay*tb; //利用加速度、速度公式计算单位时间垂直方向的即时速度

Sy0=vy*tb+ay*tb*tb/2; //利用加速度、速度、位移公式计算单位时间垂直方向的位移

Sy-=Sy0; //对垂直方向的位置坐标进行计算

y[i]=Sy;//将垂直方向的坐标存入数组y[i],数组的下标是时间单位,内容是单位时间垂直方向的位移

i++; //对数组下标进行累加,同时对用掉的单位时间进行计数,最终值为数组元素的最大个数

Fy=C*P*S*vy*vy/2; //重新计算垂直方向的即时空气阻力

ay=-Fy/m+G; //重新计算垂直方向的即时加速度

T2+=tb; //累计垂直向下运动的时间

}

//T=2*v*sin(theta_hd)/G;

T=T1+T2; //计算运动时间

printf("T=%f ",T); //输出运动时间

vx=v*cos(theta_hd); //计算水平方向的初速度

F=C*P*S*vx*vx/2; //计算水平方向的空气阻力

a=-F/m; //计算水平方向的加速度

vt=v*cos(theta_hd);//计算水平方向的即时速度

/*t=T/1000;

SS=0;

for(i=1;i<=1000;i++)

{

ss=vt*t+a*t*t/2;

vt=vt+a*t;

if(vt<=0) break;

F=C*P*S*vt*vt/2;

a=-F/m;

SS+=ss;

}*/

SS=0; //SS为水平方向的位移量

j=0; //j是水平坐标值的下标

while(T>=0) //此循环用于处理水平方向的运动,每个单位时间动态计算各项参数的值,结束条件为水平运动的事件与垂直方向运动的总时间相等

{

ss=vt*tb+a*tb*tb/2; //利用速度、时间、加速度动态计算水平方向的位移

vt=vt+a*tb; //动态计算每个事件段结束时水平方向的即时速度

if(vt<=0) break; //如果出现水平速度为负,跳出循环

F=C*P*S*vt*vt/2; //动态计算每个时间间隔结束后水平方向的空气阻力

a=-F/m; //动态计算每个时间间隔结束后水平方向的加速度

T-=tb; //没运行一次,总运行时间减去时间间隔,总运行时间减至零时,结束循环

SS+=ss; //水平位移累计

x[j]=SS; //计算每个事件间隔的水平位置,存入数组,数组下标为事件单位,内容为水平坐标

j++; //数组下标加一

}

wc=SS*tan(theta_hd); //计算需向上瞄准的距离

printf("SS=%f wc=%f\n",SS,wc); //输出水平射程,向上瞄准的距离

if((fp = fopen("/storage/emulated/0/myprogram/text.txt","w")) == NULL)

{

perror("fail to write!");

exit (1) ;

}

for(k=0;k

{

fprintf(fp,"x[%d]=%f,y[%d]=%f \n",k,x[k],k,y[k]);

}

fclose(fp);

SDL_Rect rect;

SDL_Init(SDL_INIT_EVERYTHING);

win=SDL_CreateWindow("SDL2 DRAW",0,0,1080,1920,1);

render=SDL_CreateRenderer(win,-1,NULL);

SDL_RenderClear(render);

SDL_SetRenderDrawColor(render,0,255,0,255);

for(k=0;k

{

//SDL_RenderDrawPoint(render,10*y[k],10*x[k]); //利用SDL中的绘点函数绘制曲线

//绘点函数绘出的曲线太细,为了加粗曲线,以点为中心绘制矩形。

rect = {10*y[k]+3,10*x[k]-3,7,7}; //定义矩形的顶点坐标,矩形的长、宽

SDL_RenderDrawRect(render, &rect); //绘制矩形

SDL_RenderFillRect(render, &rect); //填充矩形

}

SDL_RenderPresent(render);

SDL_Delay(50000);

return 0;

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值