- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想在游戏中实现一个物理引擎,以便计算物体在受力时的轨迹。该引擎将根据对象的先前状态计算对象的每个状态。当然,这意味着要在两个时间单位之间进行大量计算才能足够精确。
为了正确地做到这一点,我首先想知道这种获取位置的方法与运动学方程之间的差异有多大。所以我编写了这段代码,用于存储文件中模拟和方程给出的位置 (x, y, z)。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "header.h"
Body nouveauCorps(Body body, Vector3 force, double deltaT){
double m = body.mass;
double t = deltaT;
//Newton's second law:
double ax = force.x/m;
double ay = force.y/m;
double az = force.z/m;
body.speedx += ax*t;
body.speedy += ay*t;
body.speedz += az*t;
body.x +=t*body.speedx;
body.y +=t*body.speedy;
body.z +=t*body.speedz;
return body;
}
int main()
{
//Initial conditions:
double posX = 1.4568899;
double posY = 5.6584225;
double posZ = -8.8944444;
double speedX = 0.232323;
double speedY = -1.6565656;
double speedZ = -8.6565656;
double mass = 558.74;
//Force applied:
Vector3 force = {5.8745554, -97887.568, 543.5875};
Body body = {posX, posY, posZ, speedX, speedY, speedZ, mass};
double duration = 10.0;
double pointsPS = 100.0; //Points Per Second
double pointsTot = duration * pointsPS;
char name[20];
sprintf(name, "BN_%fs-%fpts.txt", duration, pointsPS);
remove(name);
FILE* fichier = NULL;
fichier = fopen(name, "w");
for(int i=1; i<=pointsTot; i++){
body = nouveauCorps(body, force, duration/pointsTot);
double t = i/pointsPS;
//Make a table: TIME | POS_X, Y, Z by simulation | POS_X, Y, Z by modele (reference)
fprintf(fichier, "%e \t %e \t %e \t %e \t %e \t %e \t %e\n", t, body.x, body.y, body.z, force.x*(t*t)/2.0/mass + speedX*t + posX, force.y*(t*t)/2.0/mass + speedY*t + posY, force.z*(t*t)/2.0/mass + speedZ*t + posZ);
}
return 0;
}
问题是,对于简单的数字(比如在 -9.81 重力场中简单下落),我得到了不错的位置,但是对于更大(且相当随机)的数字,我得到的位置不准确。
那是 float 问题吗?
这是结果,有相对误差。 (注意:标签轴是法语,Temps = Time)。
图表
最佳答案
这不是 float 问题。事实上,即使您使用精确算术,您也会遇到同样的问题。
这个错误对于数值积分本身以及您正在使用的特定方法和您正在求解的 ODE 来说是非常重要的。
在本例中,您使用的是称为正向欧拉的积分方案。这可能是求解一阶 ODE 的最简单方法。当然,这会留下一些不受欢迎的特性。
一方面,它在每一步都引入了错误。错误的大小是 O(Δt²)
.这意味着单个时间步长的误差大致与时间步长的平方成正比。因此,如果您将时间步长减半,则大致可以将增量误差降低到该值的 1/4。
但是由于你减少了时间步长,你必须做更多的步长来模拟相同的时间量。所以你加起来更多但更小的错误。这就是累积误差为 O(Δt)
的原因.因此,实际上在整个模拟时间内,如果您采用一半大的时间步长,您将获得一半的累积误差。
最终,这个累积误差就是您所看到的。您可以在误差图中看到,每次将时间步数增加 10 倍时,最终误差最终会减少约 10 倍:因为时间步长小了 10 倍,所以总误差结束小了大约 10 倍。
另一个问题是正向欧拉表现出所谓的条件稳定性。这意味着在某些情况下,累积误差可能会无限增长。要了解原因,让我们看一个简单的 ODE:
x' = -k * x
其中 k 是某个常数。此 ODE 的精确解是 x(t) = x(0) * exp( -k * t )
.所以只要k为正,x
应该倾向于0
随着时间的增加。
但是,如果我们尝试使用正向欧拉对此进行近似,我们会得到如下所示的结果:
x(t + Δt) = x(t) + Δt * ( -k * x[n] )
= ( 1 - k * Δt ) * x(t)
这是一个我们可以解决的简单递推关系:
x(t) = ( 1 - k * Δt )^(t / Δt) * x(0)
现在,我们知道十到 0 的精确解为 t
变大。但是正向欧拉解只有在 |1 - k * Δt| < 1
时才会这样做。 .请注意该表达式如何取决于步长以及 k
来 self 们的 ODE 的术语。如果k
真的很大,我们需要一个非常非常小的时间步来防止解决方案爆炸。这就是它具有所谓的条件稳定性的原因:解的稳定性取决于时间步长。
还有许多其他问题,但这是一个广泛的主题,我无法在一个答案中涵盖所有内容。
关于c++ - 物理模拟给出(非常)不准确的简单轨迹微积分位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45200210/
我有一系列 gps 值,每个值包含:timestamp, latitude, longitude, n_sats, gps_speed, gps_direction, ... ( NMEA data
我正在尝试绘制两点之间的轨迹路径。我只知道有问题的两点和它们之间的距离。我希望能够计算的是到达终点所需的速度和角度。 我还希望能够将一些重力和风因素考虑在内,这样路径/轨迹就不那么“完美”了。它用于电
有没有人对使用顶点缓冲区/4f 颜色缓冲区绘制粒子在 opengl 中对来自喷气发动机(带有加力燃烧室)的粒子流进行编码的近似值有任何指导? 我认为这个问题有两个方面: 作为温度和与燃烧的气体类型相关
问题 我正在迁移多个 ggplot/ggvis plotly 到 plotly在 shiny应用。我遇到了一个关于跟踪链接的问题。我希望能够通过 group 显示/隐藏痕迹在图例上,在相关数据框之间共
我想为玩具车在没有障碍物的平面 (2d) 上规划一条路线。玩具车应该从点 (p1x,p1y) 移动到 (p2x,p2y)(又名狄利克雷边界条件)。此外,玩具车在起点的速度是(v1x,v1y),终点处要
我正在开发一个路径/ map 应用程序,该应用程序在一个区域中绘制了自定义路径,并将帮助用户在“森林”区域的一些路径周围导航。 目前,我正在使用 MKMapView 来获取用户数据/位置,并从 KML
我目前正在尝试根据从 iPhone 视频中拍摄的一系列图像重建坠落物体(例如球或石头)的 3D 轨迹。 我应该从哪里开始寻找?我知道我必须校准相机(我想我会使用 Jean-Yves Bouguet 的
我正在尝试使用 matplotlib 在 map 上绘制 CSV 文件中的线条和标记。 数据: AL99,2017080912,SHIP,0,17.1,-55.6,25,0 AL99,20170809
我正在尝试仅使用广播源来重建篮球的 3D 轨迹。 为此,我必须计算单应矩阵,因此在每一帧中,我都成功地跟踪了球,以及它们在“现实世界”中的位置已知的 6 个点(4 个在球场上,2 个在篮板上)为在图片
如果我有一个像这样的动画圈 example , 有没有一种方法可以在 Canvas 上留下 1px 纯白色的永久痕迹? 我试过动态构建路径,但无法让它工作。 提前致谢,如有任何帮助,我们将不胜感激 最
正在工作,即将发布,没有真正的更新,[6.3.2] 突然出现此错误。 花了一天时间在 OAuthSwift V0.3.4、0.3.5、0.3.6 之间切换,同样的错误发生了。还有一次(但非常罕见),我
我正在尝试使用 matlab/octave 为这个螺旋制作动画我希望它向上或向下螺旋 t = 0:0.1:10*pi; r = linspace (0, 1, numel (t)); z = lins
我有一个有点难的算法问题,我从很多搜索中找不到任何合适的算法,所以我希望 stackoverflow 上的人可能知道答案。 我有一组车辆在 2D 空间中移动时的 x,y 坐标,坐标记录在时间段内的“决
在服务器(MySQL 或 Oracle 或任何文件)上存储 GPS 坐标(航迹)的最佳方式是什么?例如,GoogleMaps 是如何实现的?我想保存和比较相同部分的轨道。 附言我有所有必要的数据。 最
The link to download the GPS traces on OSM is quite easy to get. 但是,里面的每个文件都 super 大。而且也没有地理位置分类。所以我
这个问题与地理空间信息系统的知识有些重叠,但我认为它属于这里而不是 GIS.StackExchange 有很多应用程序处理具有非常相似对象的 GPS 数据,其中大多数由 GPX standard 定义
我正在使用此处找到的 locu-node node.js 库:https://github.com/Locu-Unofficial/locu-node ,这是 Locu 服务的 API 客户端。在提供
我正在尝试将一个元素从位置 A 动画到位置 B,但我不希望它在每个点之间线性移动,我希望有一种“抛物线”轨迹。 我可以使用 jQuery.animate() 吗? 或者我应该使用 setInterva
总结:如何避免不同线程的不同工作负载导致的性能损失? (内核在每个线程上都有一个 while 循环) 问题:我想在许多不同的初始条件下使用 Runge-Kutta 求解粒子轨迹(由二阶微分方程描述)。
我正在创建一个应用程序,其中包含一些变量的区域数据。该应用程序允许您通过 selectInput 选择用户想要可视化的区域。出于比较/信息目的,我希望用户在 plot_ly 中可视化所选区域以及全国平
我是一名优秀的程序员,十分优秀!