Ber*_*ayD 8 simulation physics game-physics
重要提示:这个问题与"PhysX" 完全没有关系,"PhysX"是一个计算机游戏物理系统(对于街机游戏中的物理学有用,如球类游戏等); PhysX是Unity3D和其他游戏引擎内置的系统; PhysX在这里完全无关紧要.
////////////////////更新(先读到底部)/////////////////////
我一直在记录值并搜索确切问题的位置,我想我找到了它.我的代码中有这样的东西
Velocity += Acceleration * Time.deltaTime;
position += Velocity * Time.deltaTime;
Run Code Online (Sandbox Code Playgroud)
加速度就像0,0000000000000009 ..现在.当代码流动时,速度应该增加,浮动没有问题.但是在开始时,地球的初始位置是(0,0,23500f)你可以在我最后给出的图表中看到这一点.
那么现在当我将速度*timedelta(此时类似于0,00000000000000005)添加到23500的位置时,它基本上不会添加它.位置仍然是(0,0,23500)不像(0,0,23500.00000000000005),因此地球不移动,因此加速度不会改变.
如果我将地球的初始位置设置为0,0,0并且仍然将加速度设置为0.0000000000000000009以使其位置为(0,0,23500)然后"ADDS"速度*timedelta.它变得类似于(0,0,000000000000000000005)并且继续增加.当float为0时,添加这么小的值没有问题.但是如果浮点数类似于23500,那么它就不会增加小值.
我不知道这是完全统一的问题还是c#的漂浮.
这就是为什么我不能让它与小值一起工作.如果我能克服这一点,我的问题将得到解决.
////////////////////////////////////////////////// /////////////////////////////
我一直在开发n体植物以模拟我们的太阳系,因此我一直在收集数据以使其尽可能逼真.但是数据大小存在问题.我搜索了每一点互联网,我找不到人们如何克服这一点的单一解释.(如果是这样的话)所以我在这里尝试拍摄.
因此,为了保持行星之间的距离,半径和"质量"的比例,我创建了一个excel文件来计算所有数据.(因为有人为什么会把"地球的质量如果有"那个"半径图"在互联网上?)我将把ss作为附件.它基本上"标准化"或换句话说"缩放"行星的每个属性到给定的参考.在这种情况下,我把参考作为"地球的半径".
我团结一致,你知道,你不能在统一中使用"太大"或"太小"的价值观.所以我不得不缩小太阳能系统,"很多!"
因此,我使用牛顿万有引力定律,即F = GMm/r ^ 2,使其变得简单,我直接计算a = GM/r ^ 2,对于来自所有其他物体的给定物体.
因此,地球的"朝向太阳"的重力加速度的实际值大约是0,000006 km/s ^ 2,这在统一的工作中甚至是非常小的值,但它可以工作.然而,为了获得这个值,1我需要将地球的半径(比例)设置为6371单位,并将太阳比例设置为696,342 !,这对于将其统一起来来说太大了.
所以我说,让地球的半径为1,以统一为单位.因此,当半径改变时,一切都会改变,质量,距离......我保持行星的密度,并用新半径计算新体积的质量.所有计算都在附件中.
所以事实是,当我把地球的半径变为1时,对太阳的引力加速就像0,0000000000009那样小得可笑.当然,Unity不会使用这个值.
所以,如果我改变地球的半径,那么太阳的质量和半径变得非常大,然后再次,我无法使用它.
我不知道其他人如何解决这个问题,他们为解决这个问题做了什么,但正如我从这里看到的那样,看起来不可能对太阳系进行逼真的n体模拟.(至少统一)
所以我需要有10个代表来发布图片-_-,我会给出链接. http://berkaydursun.com/solar_system_simulator/data.PNG 另外一个目录是使用n体计算但具有UNREALISTIC值的工作实验太阳系模拟.它工作得很好,它甚至看起来有点接近真实,但不,它没有正确的比率^^你可以在这里测试它,如果你希望http://berkaydursun.com/solar_system_simulator/
编辑:WoW我几乎用"So"开始了每个段落^^
Spe*_*tre 14
我也做了程序溶胶系统模拟,所以这里是我的见解:
翻译
我使用OpenGL以1:1缩放.所有单位都是SI所以[m,s,kg,...].问题从Z-buffer开始.通常的Z缓冲区位宽16/24/32 bit
不足以满足您的需求.我正在渲染0.1米到1000澳元,那么如何解决这个问题呢?
我通过组合Z-sorting和Z-buffering一起渲染3个frustrums来管理它(由于透明环......和其他效果,Z-sort是必要的).所以首先我将最远的部分渲染到zfar=1000AU
.天空圆顶投射到z=750AU
距离然后清除Z缓冲区并渲染对象zfar=0.1AU
.然后再次清除Z缓冲区并渲染近处的对象zfar=100000 m
.
要完成这项工作,您必须拥有尽可能精确的投影矩阵.该gluPerspective
有unprecise cotangens所以它需要修复有关的元素(让我很长的时间来发现这一点).Z near
值取决于Z缓冲区的位宽.如果编码正确,那么即使使用缩放也能正常工作10000x
.我使用这个程序作为矿山望远镜对象的导航/搜索器:)从我的家庭视图实时.我结合了3D星,天文体,船只,真实地面(通过DTM和卫星纹理).它甚至能够产生红 - 青色立体输出:).可以从表面,大气,空间渲染......(不仅仅是锁定在地球上).没有其他第三方lib然后使用OpenGL.这是它的样子:
模拟
我没有使用n体重力模拟,因为你需要大量非常难以获得的数据(并且几乎不可能达到所需的精度).计算必须非常精确.
我使用开普勒方程式,所以看看这些:
如果你仍然想使用引力模型,然后使用喷气推进实验室的视野从美国航空航天局.我认为他们在C/C++中也有源代码,但他们使用不兼容的参考框架和我的地图,所以它对我来说无法使用.
一般来说,开普勒方程具有更大的误差,但它并没有随着时间的推移而增加.重力模型更精确但其误差随着时间的推移而增加,您需要不断更新astro体数据以使其工作......
[edit1]集成精度
您当前的实现是这样的:
// object variables
double acc[3],vel[3],pos[3];
// timer iteration
double dt=timer.interval;
for (int i=0;i<3;i++)
{
vel[i]+=acc[i]*dt;
pos[i]+=vel[i]*dt;
}
Run Code Online (Sandbox Code Playgroud)
问题是当你添加非常小且非常大的值时,它们会在添加之前转移到相同的指数,这将使重要数据四舍五入.为了避免这种情况,只需将其更改为:
// object variables
double vel0[3],pos0[3]; // low
double vel1[3],pos1[3]; // high
double acc [3],vel [3],pos [3]; // full
// timer iteration
double dt =timer.interval;
double max=10.0; // precision range constant
for (int i=0;i<3;i++)
{
vel0[i]+=acc[i]*dt; if (fabs(vel0[i]>=max)) { vel1[i]+=vel0[i]; vel0[i]=0.0; } vel[i]=vel0[i]+vel1[i];
pos0[i]+=vel[i]*dt; if (fabs(pos0[i]>=max)) { pos1[i]+=pos0[i]; pos0[i]=0.0; } pos[i]=pos0[i]+pos1[i];
}
Run Code Online (Sandbox Code Playgroud)
现在xxx0
已经整合到max
了,整个事情都被添加到了xxx1
四舍五入仍然存在,但它不再累积.您必须选择max
集成本身是安全的值,并且添加xxx0+xxx1
必须是安全的.因此,如果一个分裂的数字太不相同,则分割两次或更多次......
xxx0+=yyy*dt; if (fabs(xxx0>max0))... if (fabs(xxx1>max1))...
[Edit2]明星
[Edit3]进一步提高Newton d'Lambert的集成精度
迭代积分的基本问题是,基于当前身体位置来应用基于引力的加速将导致更大的轨道,因为在整合步骤中dt
,位置改变了一点,这在初始积分中没有考虑.要解决这个问题,请看一下这张图片:
假设我们的身体处于圆形轨道并处于0度位置.而不是使用基于当前位置的加速度方向我使用后的位置0.5*dt
.这增加了加速度小位,从而产生了更高的精度(与开普勒轨道的对应关系).通过这个调整,我能够成功地从开普勒轨道转换为Newton d'Lambert的2体系统.(为n-body执行此操作是下一步).与我们的太阳系的实际数据粗略相关只能用于不受潮汐效应和/或卫星影响的2体系统.要构建自己的虚构数据,您可以使用开普勒圆轨道和重力均衡重力:
G = 6.67384e-11;
v = sqrt(G*M/a); // orbital speed
T = sqrt((4.0*M_PI*M_PI*a*a*a)/(G*(m+M))); // orbital period
Run Code Online (Sandbox Code Playgroud)
a
圆形轨道半径在哪里是m
体重,M
是焦点体质(太阳).为了保持精度在可接受的容差范围内(对我而言),集成步骤dt
应该是:
dt = 0.000001*T
Run Code Online (Sandbox Code Playgroud)
因此,将新机构用于测试只需将其放在:
pos = (a,0,0)
vel = (0,sqrt(G*M/a),0)
Run Code Online (Sandbox Code Playgroud)
主要焦点机构(Sun)位于:
pos = (0,0,0)
vel = (0,0,0)
Run Code Online (Sandbox Code Playgroud)
这将使您的身体处于圆形轨道,这样您就可以比较Kepler和Newton d'Lambert来评估模拟的精确度.
归档时间: |
|
查看次数: |
6079 次 |
最近记录: |