3d 房间中 2 条曲线的碰撞点
我正在编写一个小游戏有一段时间了。我们开始在学校的一个项目中编写一个小型 FPS-Shooter,以获得使用 directX 的一些经验。 我不知道为什么,但我无法停止这个项目并开始在家编程。目前我正在尝试创建一些小型人工智能。当然,这绝对不容易,但无论如何,这就是我的个人目标。这个话题可能会填满多本书,呵呵。 到目前为止,我已经完成了机器人的行走部分。他们沿着一条刻有文字的小路行走。我不是在研究机器人的“瞄准”。 在编程时,我遇到了一些我还无法解决的数学问题。我希望您对此的意见能够帮助我走得更远。概念、想法和其他一切都受到高度赞赏。
问题: 计算弹丸曲线(取决于重力、速度)击中敌人行走路径曲线(取决于速度)的位置(D3DXVECTOR3)。我们假设敌人排成一条直线行走。
已知变量:
float projectilSpeed = 2000 m/s //speed of the projectile per second
float gravitation = 9.81 m/s^2 //of cause the gravity lol
D3DXVECTOR3 targetPosition //position of the target stored in a vector (x,y,z)
D3DXVECTOR3 projectilePosition //position of the projectile
D3DXVECTOR3 targetSpeed //stores the change of the targets position in the last second
Variabledefinition
ProjectilePosition at time of collision = ProjectilePos_t
TargetPosition at time of collision = TargetPos_t
ProjectilePosition at time 0, now = ProjectilePos_0
TargetPosition at time 0, now = TargetPos_0
Time to impact = t
Aim-angle = theta
我的尝试: 在维基百科上找到了一个计算“落差”(基于重力的弹丸下落)的公式:
float drop = 0.5f * gravity * t * t
弹丸的速度有水平部分和垂直部分。也在维基百科上找到了一个公式:
ProjectilVelocity.x = projectilSpeed * cos(theta)
ProjectilVelocity.y = projectilSpeed * sin(theta)
所以我假设这是对于弹丸曲线为真:
ProjectilePos_t.x = ProjectilePos_0.x + ProjectileSpeed * t
ProjectilePos_t.y = ProjectilePos_0.y + ProjectileSpeed * t + 0.5f * gravity * t * t
ProjectilePos_t.z = ProjectilePos_0.z + ProjectileSpeed * t
目标以恒定速度行走,因此我们可以通过以下方式确定他的曲线:
TargetPos_t = TargetPos_0 + TargetSpeed * D3DXVECTOR3(t, t, t)
现在我不知道如何继续。我必须以某种方式解决它,才能抓住时间以某种方式产生影响。 作为一个基本公式,我可以使用:
float time = distanz / projectileSpeed
但这并不是真正正确的,因为它会假设线性“轨迹”。我们只是在使用火箭时发现了这种行为。
我希望我能够尽可能多地解释这个问题。如果还有疑问,请随时问我!
来自德国的问候, 坦率
Edit:
主要问题是我无法计算碰撞时敌人的位置,因为我没有经过碰撞发生之前的时间。另一方面,如果不知道碰撞时敌人的位置,我就无法计算时间。也许迭代方法可以解决这个问题。
曲线敌人:
pos(t).x = pos(0).x + speed.x * time
pos(t).y = pos(0).y + speed.y * time
pos(t).z = pos(0).z + speed.z * time
曲线射弹: pos(t).y = pos(0).y + sin(theta) * 速度 + 0.5 * 重力 * 时间 * 时间
pos(t).x 和 pos(t).z 不确定如何计算 (x 和z)基本上定义前进方向..不仅仅是x..
在不知道时间的情况下无法计算敌人..并且在不知道角度(theta,俯仰/偏航)和距离的情况下我无法计算时间它将到达“未来”的撞击点
i am programming a small game for quite some time. We started coding a small FPS-Shooter inside of a project at school to get a bit experience using directX.
I dont know why, but i couldnt stop the project and started programming at home aswell. At the moment i am trying to create some small AI. Of cause thats definatlly not easy, but thats my personal goal anyways. The topic could prolly fill multiple books hehe.
I've got the walking part of my bots done so far. They walk along a scriped path. I am not working on the "aiming" of the bots.
While programming that i hit on some math problem i couldnt solve yet. I hope of your input on this to help me get further. Concepts, ideas and everything else are highly appreciated.
Problem:
Calculate the position (D3DXVECTOR3) where the curve of the projectile (depends on gravity, speed), hit the curved of the enemys walking path (depends on speed). We assume that the enemy walks in a constant line.
Known variables:
float projectilSpeed = 2000 m/s //speed of the projectile per second
float gravitation = 9.81 m/s^2 //of cause the gravity lol
D3DXVECTOR3 targetPosition //position of the target stored in a vector (x,y,z)
D3DXVECTOR3 projectilePosition //position of the projectile
D3DXVECTOR3 targetSpeed //stores the change of the targets position in the last second
Variabledefinition
ProjectilePosition at time of collision = ProjectilePos_t
TargetPosition at time of collision = TargetPos_t
ProjectilePosition at time 0, now = ProjectilePos_0
TargetPosition at time 0, now = TargetPos_0
Time to impact = t
Aim-angle = theta
My try:
Found a formular to calculate "drop" (Drop of the projectile based on the gravity) on Wikipedia:
float drop = 0.5f * gravity * t * t
The speed of the projectile has a horizontal and a vertical part.. Found a formular for that on wikipedia aswell:
ProjectilVelocity.x = projectilSpeed * cos(theta)
ProjectilVelocity.y = projectilSpeed * sin(theta)
So i would assume this is true for the projectile curve:
ProjectilePos_t.x = ProjectilePos_0.x + ProjectileSpeed * t
ProjectilePos_t.y = ProjectilePos_0.y + ProjectileSpeed * t + 0.5f * gravity * t * t
ProjectilePos_t.z = ProjectilePos_0.z + ProjectileSpeed * t
The target walk with a constant speed, so we can determine his curve by this:
TargetPos_t = TargetPos_0 + TargetSpeed * D3DXVECTOR3(t, t, t)
Now i dont know how to continue. I have to solve it somehow to get a hold on the time to impact somehow.
As a basic formular i could use:
float time = distanz / projectileSpeed
But that wouldnt be truly correct as it would assume a linear "Trajectory". We just find this behaivor when using a rocket.
I hope i was able to explain the problem as much as possible. If there are questions left, feel free to ask me!
Greets from germany,
Frank
Edit:
The main problem is that i cant calculate the enemies position at collision time as i dont have the time passed until the collision occurs.. And on the other hand i cant calculate the time without knowing the enemies location at impact time. Maybe an iterative method solves this.
curve enemy:
pos(t).x = pos(0).x + speed.x * time
pos(t).y = pos(0).y + speed.y * time
pos(t).z = pos(0).z + speed.z * time
curve projectile:
pos(t).y = pos(0).y + sin(theta) * speed + 0.5 * gravity * time * time
pos(t).x and pos(t).z not sure how to calculate in (x and z) define the forward direction basically.. not just x..
cant calculate the enemy without knowing the time.. and i cant calculate the time without knowing the angles (theta, pitch/yaw) and the distance it will be to the "future" impact point
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这不是一个完整的解决方案,而是我如何从数学的角度来解决这个问题。
你有两个想要见面的对象。您需要找到的三个未知数是击中发生的时间、击球的垂直角度和击球的水平角度。
您只需通过说出(此处以向量形式)即可知道目标在任何时间 t 的位置
。
射弹的位置将是:(
同样是矢量,因此这里的初始速度将取决于射击的两个角度)
当我们受到击中时,显然这两个位置将是相同的,因此我们可以将这两个位置等同。
我们知道有效地存在具有三个未知数的向量方程。如果我们将其分解为分量向量,那么每个方程仅适用于向量的 x、y 和 z 分量(请注意,加速度仅具有 z 方向的分量)。
然后我们得到三个具有三个未知数的方程,这些方程将同时求解。我将剩下的留给你的主要原因是因为我不知道如何在我的答案中以一种很好的方式表示代数。 :)
抱歉,这不是更完整,但希望可以给您一种看待事物的新方式,并且您可能能够自己完成数学工作,自己求解方程(不难,但同时也不那么容易...... .)
Not a complete solution but how I would approach this from a mathemtical point of view.
You have two objects that you want to meet. The three unknowns you need to find are time at which the hit occurs, vertical angle of shot and horizontal angle of shot.
You know the position of the target at any time t just by saying
(in vectors here).
The position of the projectile will be:
(again vectors so the initial velocity here will be dependant on the two angles of the shot)
When we get a hit obviously these two positions will be the same so we can equate these two positions.
We know have a vector equation with three unknowns effectively. If we then split it into its component vectors then each of those equations holds for just the x, y and z components of the vectors (note that acceleration only has a component in the z direction).
We then get three equations with three unknowns that will be solved simultaneously. The main reason I am going to leave the rest to you is because I have no idea how I'd represent the algebra in my answer in a nice way. :)
Sorry this isn't more complete but hopefully may give you a new way of looking at things and you might be able to work through the maths yourself to solve the equations yourself (not hard but at the same time not that easy...)
首先,当您使用 C++ 时,确实值得广泛使用重载算术运算符,因此向量运算。您的公式将看起来更加清晰且更接近数学定义。您很少需要显式的
.x
、.y
赋值。现在回答你的问题:
是的,时间就是要走的路。
想象一下您同时向各个可能的方向射击。在任何给定时间,所有射弹都会在空气中的某个地方形成一个不断膨胀的球体。现在,您可以将该球体与目标的路径相交,并获取可能发生命中的时间。数学运算有点棘手(求解四次多项式方程),但它可以很好地近似。
作为德国人,您一定应该看看这篇德语文章,其中涵盖了话题好!
first of all, as you're going with C++, it's really worth using the overloaded arithmetic operators and thus vector operations extensively. Your formulae are going to look much cleaner and closer to the mathematical definitions. You're rarely going to ever need explicit
.x
,.y
assignments at all.So now to your question:
Yes, time is the way to go.
Imagine you shoot in every possible direction at the same time. All projectiles will form an expanding sphere somewhere in the air at any given time. You can now intersect this spheres with the path of the target and get times when a hit can occur. Maths for this is just a bit tricky (solving polynomial equations of degree four), but it works well with approximation.
As you're German, you should definitely take a look at this german article that covers the topic nicely!
如果敌人以恒定速度(即直线)行走,最简单的方法是更改变量,以便将所有内容写入敌人的移动框架中。然后,您需要求解一个二次方程。
但在现实世界中,有很多敌人,当你射击时,你必须测试你的子弹在t时刻是否与某些敌人形状相交(敌人不是点)。所以你发射子弹,用快速 ODE 解算器模拟它的轨迹:我认为龙格库塔四阶是常用的,不是因为它的准确性(你无法轻松控制误差,并且你不需要物理准确性:只需要真实感。不要使用 RK4 来求解 ODE(视频游戏除外),但因为您可以采取相对较大的时间步长而不会太偏离。
实际上,模拟游戏的物理原理(玩家和敌人的物理原理以及 IA、子弹……)需要您记录时间。然后,您迭代子弹并测试它们与游戏的各种对象(主要是敌人)的相交。
每次,计算交集的典型方法是使用八叉树来跟踪对象的位置。在给定时间,该设备使您能够轻松定位(log n)与子弹位于同一空间区域的敌人。现在,您可以使用:
If the enemy is walking at a constant velocity (ie. in a straight line), the simplest way is to change variables so that you write everything in the moving frame of the enemy. Then, you have a quadratic equation to solve.
But in the real world, there are many enemies, and when you shoot, you have to test whether your bullet at time t intersects some enemy shape (enemies are not points). So you fire your bullet, simulate its trajectory with fast ODE solver: Runge Kutta 4th order is commonly used I think, not for its accuracy (you have no easy control of the error, and you don't need physical accuracy: only realism. Don't use RK4 for solving ODEs except in video games) but because you can take relatively large time steps without being too off.
Actually, simulating the physics of the game (players and enemies physics and IA, bullets, ...) requires you to keep track of time. You then iterate over the bullets and test for their intersection with various objects of the game (mainly enemies).
At each time, the typical way to compute intersections is to use an octree to keep track of where the objects are. At a given time, this device enables you to locate easily (log n) the enemies which lie in the same region of space as the bullet. Now, you can use: