⭐✔️
本帖最后由 贰逼 于 2015-10-29 21:12 编辑

本人这些天费劲心思,终于探究出了Minecraft物理系统的工作方式,并编写了此软件供大家使用。


使用方式:




1.找到Motion by Speed一栏;
2.填写RotationXRotationYSpeed
3.按下Work out Motion按钮即可。


4.点击ClearAll按钮清空所有。


1.填写起点坐标终点坐标(有没有填写的会有提示);


2.填写加速度阻力抛射角度
3.点击Work out Motion生成,注意不是所有角度都符合条件,如果不符合条件会有提示




4.填写一个正确的抛射角度后,点击Work out Motion算出Motion值。




6.点击Export Rotation按钮生成NBT的Rotation。

由于不是所有抛射角度都能经过最终坐标/测试Motion速度效果,所以本软件自带画线功能。(画线指平面对运动轨迹视图)




1.在得到Motion后(可以自行填写),点击Draw the line画出运动轨迹。



2.点击确定。如果拥有起点坐标,左上会写出起点坐标;如果有终点坐标,两条直线交点则是终点坐标



3.点击Clear the line清空画线面板。



4.修改画面比例可以得到全图运动轨迹。通过速度算出的Motion可以算出最终距离起点多少长度。



5.同样按下确定,如果有,能够显示起点坐标终点坐标



6.点击ClearAll按钮清空所有。


英文看不懂、参数看不透?

点击文字获得更多信息



下一页为算法;

第三页为下载地址;


2021.12 数据,可能有更多内容楼主本人对Minecraft物理系统十分感兴趣。在几年前就看到国外有大神通过TNT大炮算出了Mc物理抛物线,虽然也不知道对不对,但是总感觉好高端的样子。


在1.7更新了NBT标签后,有一个所有实体共享的标签:Motion。
在实验了几次后,发现Motion是一个控制物体运动的标签。
他包含三个双精度浮点值。
当初对于Minecraft运动涉世未深,所以国内国外关于这几乎一片空白。


在1.8后大致知道了这三个量分别是向x轴,y轴,z轴移动速度(单位 方块/刻)
然而试验了几次并不理想。本人这些天费劲心思,终于探究出了Minecraft物理系统的工作方式,并编写了此软件供大家使用。


使用方式:


  • 通过方向和方向上的速度算Motion值


1.找到Motion by Speed一栏;
2.填写RotationXRotationYSpeed
3.按下Work out Motion按钮即可。



4.点击ClearAll按钮清空所有。


  • 通过起点坐标和终点坐标算Motion

1.填写起点坐标终点坐标(有没有填写的会有提示);



2.填写加速度阻力抛射角度
3.点击Work out Motion生成,注意不是所有角度都符合条件,如果不符合条件会有提示





4.填写一个正确的抛射角度后,点击Work out Motion算出Motion值。





6.点击Export Rotation按钮生成NBT的Rotation。


  • 画线功能
由于不是所有抛射角度都能经过最终坐标/测试Motion速度效果,所以本软件自带画线功能。(画线指平面对运动轨迹视图)





1.在得到Motion后(可以自行填写),点击Draw the line画出运动轨迹。





2.点击确定。如果拥有起点坐标,左上会写出起点坐标;如果有终点坐标,两条直线交点则是终点坐标





3.点击Clear the line清空画线面板。





4.修改画面比例可以得到全图运动轨迹。通过速度算出的Motion可以算出最终距离起点多少长度。





5.同样按下确定,如果有,能够显示起点坐标终点坐标





6.点击ClearAll按钮清空所有。


  • 贴心功能

英文看不懂、参数看不透?
点击文字获得更多信息


下一页为算法;
第三页为下载地址;


算法1——速度+方向算Motion


速度 就是这个方向上的速度
那么通过这个方向反过来可以分别求出向x轴,y轴,z轴的速度。(此处轴的方向为正方向)


sp:速度;
xyzmov:分别的Motion;
xdeg:Rx角度;
ydeg:Ry角度。





通过上图可以得知:


代码:


  1. xmov = sp * sin(xdeg) * cos(ydeg)
  2. ymov = sp * sin(ydeg)
  3. zmov = sp * cos(xdeg) * cos(ydeg)

绿线则是ymov,蓝线是zmov,紫线是xmov。


由于Mc中的Ry略有特殊,所以真正算法是:

代码:

  1. xmov = -sp * sin(xdeg) * cos(ydeg)
  2. ymov = sp * sin(ydeg)+0.1
  3. zmov = sp * cos(xdeg) * cos(ydeg)
其中y+0.1是为了保持运动。


算法2——两坐标算方向

前面提到了Ry,Rx有些特别,


根据规律:




Rx:




Ry:






代码:

  1. <b style="font-size: x-large;">    </b><font size="1">Rx = atan2(delZ, delX)
  2.     Ry = atan2(delY,Sqrt(delX * delX + delZ * delZ)))</font>
其中:


delX,delZ,delY是表示终点坐标减去起点坐标;
Sqrt就是开方。


具体还需要自己体会。

算法3——两坐标算Motion


这个问题困扰了我几天,
我试过斜抛公式

代码:

  1. v = f + (Math.Sqrt(g * lenx * lenx) / (Math.Cos(d * Math.PI / 180) * Math.Sqrt(2 * lenx * Math.Tan(d * Math.PI / 180) - leny))) * Math.PI
也试过二次函数抛物线,但是都不是。


后来无耻的翻源码,才发现Minecraft物理运动系统其实比较偷懒

代码:

  1.   this.posX += this.motionX;
  2.   this.posY += this.motionY;
  3.   this.posZ += this.motionZ;

  4.   this.motionX *= (double)var18;
  5.   this.motionY *= (double)var18;
  6.   this.motionZ *= (double)var18;
  7.   this.motionY -= (double)var19;
  8.   this.setPosition(this.posX, this.posY, this.posZ);
其中:
var19=g=加速度(其实应该是重力,不过wiki里面说没有重力所以命名加速度,这有点误导)
var18=f=1-阻力


加速度和阻力可以去WIKI查看(其中包含运动一栏):
http://minecraft-zh.gamepedia.com/%E5%AE%9E%E4%BD%93
http://minecraft.gamepedia.com/Entity


经过进一步整理

代码:

  1. x=mx+fmx+f^2 mx+……+f^t mx
  2. =(f^0+f^1+f^2+……+f^t)mx

因为mx mz关于rx关联,所以合并成一个mx
再整理:

代码:

  1. mx=x/(-100(0.99^t-1))
  2. my=(y+gt)/(-100(0.99^t-1))
其中要使mx my有关联,
可以设定抛射角度θ


因此能进一步推导t,也可以通过另类求法:



此处的t就是
(无重力的y坐标-最终坐标)/重力
不该是推导还是这种求法,得到的t:

代码:

  1. θ<45
  2. tan(θ)=my/mx=(y+gt)/10(1-0.99^t)*10(1-0.99^t)/x=(y+gt)/x
  3. y+gt=x*tan(θ)
  4. gt=x*tan(θ)-y
  5. t=(x*tan(θ)-y)/g

  6. θ>45
  7. tan(90-θ)=mx/my
  8. t=(x/tan(90-θ)-y)/g

求出t后,mx my mz只需要:

代码:

  1.     motx = delX / (-100 * (Math.Pow(1 - d, t) - 1));
  2.     moty = (delY + G * t) / (-100 * (Math.Pow(1 - d, t) - 1)) + 0.1;
  3.     motz = delZ / (-100 * (Math.Pow(1 - d, t) - 1));
(Math.Pow代表x的n次幂)


由于角度不能偏值太大,否则t太大,得出的Motion不准确,所以设定了一个范围(具体这个范围就不解释了)
总之角度越接近Rotation中的Ry,运动得越远


具体可以使用画线功能看看运动是否经过终点坐标

下载地址:
链接:http://pan.baidu.com/s/1mg8DOt6
密码:n7tk



乾.坤
丧心病狂,不过真的很不错,支持!

小白~别喷。
嗯,LZ高产啊。。

卡林
二逼赛高

陈继之
我去,好复杂,好sang牛xin逼bing啊kuang

langyo
= =在2个平面中分别计算抛物线

不容易啊……

赞一个吧

Deing
楼主这么厉害!!想必物理大神!

死神灬
不错啊{:10_492:}

dasdas4124
赞赞赞赞赞赞

brave_heart
貌似看起来很有用也

爱心魔王FHC
图标的像素不能做高点么,或者直接拿MC里的方块更好

MingHao_
看不懂啊。
都没学过物理

jajamu
真的好的厉害!!!

Darkdomain·
66666,好厉害!!!{:10_509:}

Big_雨熙
高级高级- -看上去好66

Mine268
二次函数就可以把我整死了。。

RedStoneMC
存档名称竟然是L4D2...不过求生的话的确用途很大的,就是不能解决连续攻击,怪物被攻击后会有半秒无敌时间

⭐✔️
RedStoneMC 发表于 2016-5-3 21:40
存档名称竟然是L4D2...不过求生的话的确用途很大的,就是不能解决连续攻击,怪物被攻击后会有半秒无敌时间 ...

mc本身的特性

Hykilpikonna
求源代码

cesium_fluoride
本帖最后由 cesium_fluoride 于 2016-5-24 17:45 编辑
Minecraft物理运动系统其实比较偷懒

偷个毛线懒啊{:10_493:}...那就是欧拉折线法,微分方程的数值解法...
===============================================
粗体表示向量。r表示位矢,或者说物体的位置向量。
这是速度的定义式:
v=dr/dt

这是加速度的定义式:
a=dv/dt
游戏里木有引入"质量"这一概念,因此用加速度替代物体受力进行计算,或者说可以认为质量m已经被从公式两端约去了。
加速度由两部分组成,重力(加速度)g与阻力(加速度)f=-γv,γ表示阻尼系数。
即有"受力":
a=g+f=g-γv
代入并整理得运动方程
dr/dt=v
dv/dt=g-γv

dr=vdt
dv=gdt-γvdt
所谓欧拉折线法,找了张比较直观的图:

在公式里的简单体现就是粗暴地把微分号d替换为差分号Δ,即:
Δr=vΔt
Δv=gΔt-γvΔt
取每一步的时间变化Δt=1,单位为game tick,于是乎:
Δr=v
Δv=g-γv
亦即:
r(t+1)-r(t)=v(t)
v(t+1)-v(t)=g-γv(t)
化为:
r(t+1)=v(t)+r(t)
v(t+1)=(1-γ)v(t)+g
写成分量得:
x(t+1)=x(t)+vx(t)
y(t+1)=y(t)+vy(t)
z(t+1)=z(t)+vz(t)

vx(t+1)=(1-γ)vx(t)
vy(t+1)=(1-γ)vy(t)-g
vz(t+1)=(1-γ)vz(t)
写成代码就是那一段"偷懒"的东西了:
  1. this.posX += this.motionX;
  2. this.posY += this.motionY;
  3. this.posZ += this.motionZ;

  4. this.motionX *= (double)var18;
  5. this.motionY *= (double)var18;
  6. this.motionZ *= (double)var18;
  7. this.motionY -= (double)var19;
复制代码
这么干最大的优点在于你可以随时引入其他的"受力"。程序上的实现暂且不提,在以上推导里的体现则是在a=g+f之上添加其他项,比如a=g+f+f1+f2之类的东西。
所谓斜抛公式神马的都只是运动方程的解,作为死板但通用的方法是把那个方程分离变量啊积分啊什么的得到。方程比较简单的时候还好办,复杂了以后(比如在受力里面添加一些奇葩的项)积分都未必积得出解析式,只能求数值解;而这种时候还不如从一开始就直接对方程求数值解好办。

⭐✔️
cesium_fluoride 发表于 2016-5-24 10:36
偷个毛线懒啊...那就是欧拉折线法,微分方程的数值解法...
================================== ...

不多说了 当初码字也就随便码码 凑合着用

LCSDB
迷样的黑科技GET

爱心魔王FHC
今天用这个软件的时候才发现太复杂了
比如我想要通过Motion把装备架射出6格远
但……加速度和阻力是什么鬼……这怎么填= =

第一页 上一页 下一页 最后一页