Thursday, June 30, 2022
HomeGame Developmentphysics - Mannequin path of bullet to hit future place of balloon

physics – Mannequin path of bullet to hit future place of balloon


If I perceive accurately, the targets transfer alongside a path outlined as a sequence of factors. So, successfully, it’s shifting alongside a sequence of straight segments, right?

Thus, you may:

  1. Clear up the time and place for the collision alongside the present section.
  2. Test if that place is past the top of the section.
  3. Whether it is, add a time offset for the time to achieve the top of the section, take the subsequent section as present, and repeat from step 1.
  4. For those who nonetheless haven’t discovered a viable interception after contemplating the final path section, then you definately can’t intercept this goal. Attempt a special goal, wait, or shoot to overlook.

Is sensible?


Okay, we now have:

  • The shooter place. I will name it s_pos.
  • The bullet velocity. I will name it b_speed.
  • The goal preliminary place. I will name it t_pos_0.
  • The goal velocity. I will name it t_vel.
  • The time offset. I will name it time_0.

And we wish:

  • Collision time.
  • Collision place.

We all know that the gap the bullet would have traveled in operate of time is:

b_travel_dist(time) = b_speed * time_0 + b_speed * time

I will take the primary phrases to be computed earlier than hand:

b_travel_dist_0 = b_speed * time_0

And now we now have:

b_travel_dist(time) = b_travel_dist_0 + b_speed * time

If we are able to discover the operate of the gap of the goal to the shooter by way of time, the purpose the place these features cross is the answer.

We will begin with the place of the goal as a operate of time:

t_pos(time) = t_pos_0 + t_vel * time

After which the offset between goal and shooter as a operate of time:

ts_offset(time) = t_pos(time) - s_pos

After which their distance:

ts_dist(time) = size(ts_offset(time))

So we are able to equate the gap between goal and shooter and the gap the bullet traveled:

ts_dist(time) = b_travel_dist(time)

Changing:

size(t_pos_0 + t_vel * time - s_pos) = b_travel_dist_0 + b_speed * time

Truly, I need to reorganize it in order that the phrases that would not have time are collectively:

size(t_pos_0 - s_pos + t_vel * time) = b_speed * time

In reality, you’ll be able to take these to compute beforehand too:

ts_offset_0 = t_pos_0 - s_pos

And we now have rather less cognitive load:

size(ts_offset_0 + t_vel * time) = b_travel_dist_0 + b_speed * time

After which we clear up for time (we in fact know the time should be constructive)… Hmm…

Look, we are able to divide by time on either side (take your time to assume it by):

size(ts_offset_0/time + t_vel) = b_travel_dist_0/time + b_speed

Okay, allow us to separate the x and y parts:

sqrt
(
    (ts_offset_0.x/time + t_vel.x)^2
    +
    (ts_offset_0.y/time + t_vel.y)^2
)
=
b_travel_dist_0/time + b_speed

So we are able to sq. either side:

(ts_offset_0.x/time + t_vel.x)^2
+
(ts_offset_0.y/time + t_vel.y)^2
=
(b_travel_dist_0/time + b_speed)^2

Allow us to develop these:

(ts_offset_0.x/time)^2 + 2*(ts_offset_0.x/time)(t_vel.x) + (t_vel.x)^2
+
(ts_offset_0.y/time)^2 + 2*(ts_offset_0.y/time)(t_vel.y) + (t_vel.y)^2
=
(b_travel_dist_0/time)^2 + 2*(b_travel_dist_0/time)(b_speed) + (b_speed)^2

Reorganize:

  (ts_offset_0.x/time)^2
+ (ts_offset_0.y/time)^2
+ 2*(ts_offset_0.x/time)(t_vel.x)
+ 2*(ts_offset_0.y/time)(t_vel.y)
+ (t_vel.x)^2
+ (t_vel.y)^2
=
  (b_travel_dist_0/time)^2
+ 2*(b_travel_dist_0/time)(b_speed)
+ (b_speed)^2

Reorganize more durable:

  (ts_offset_0.x)^2/time^2
+ (ts_offset_0.y)^2/time^2
+ 2*(ts_offset_0.x)(t_vel.x)/time
+ 2*(ts_offset_0.y)(t_vel.y)/time
+ (t_vel.x)^2
+ (t_vel.y)^2
=
  (b_travel_dist_0)^2/time^2
+ 2*(b_travel_dist_0)(b_speed)/time
+ (b_speed)^2

Reorganize more durable:

  ((ts_offset_0.x)^2 + (ts_offset_0.y)^2)/time^2
+ (2*(ts_offset_0.x)(t_vel.x) + 2*(ts_offset_0.y)(t_vel.y))/time
+ (t_vel.x)^2 + (t_vel.y)^2
=
  (b_travel_dist_0)^2/time^2
+ 2*(b_travel_dist_0)(b_speed)/time
+ (b_speed)^2

Allow us to multiply every thing by time squared:

  (ts_offset_0.x)^2 + (ts_offset_0.y)^2
+ time * (2*(ts_offset_0.x)(t_vel.x) + 2*(ts_offset_0.y)(t_vel.y))
+ time^2 * (t_vel.x)^2 + (t_vel.y)^2
=
  (b_travel_dist_0)^2
+ time * 2*(b_travel_dist_0)(b_speed)
+ time^2 * (b_speed)^2

Reorganize once more:

  time^2 * (t_vel.x)^2 + (t_vel.y)^2
+ time * (2*(ts_offset_0.x)(t_vel.x) + 2*(ts_offset_0.y)(t_vel.y))
+ (ts_offset_0.x)^2 + (ts_offset_0.y)^2
=
  time^2 * (b_speed)^2
+ time * 2*(b_travel_dist_0)(b_speed)
+ (b_travel_dist_0)^2

Ah, a quadratic equation in canonical type:

  time^2 * ((t_vel.x)^2 + (t_vel.y)^2 - (b_speed)^2)
+ time * ((2*(ts_offset_0.x)(t_vel.x) + 2*(ts_offset_0.y)(t_vel.y)) - 2*(b_travel_dist_0)(b_speed))
+ (ts_offset_0.x)^2 + (ts_offset_0.y)^2 - (b_travel_dist_0)^2
=
0

Allow us to take the elements out:

a = (t_vel.x)^2 + (t_vel.y)^2 - (b_speed)^2
b = (2*(ts_offset_0.x)(t_vel.x) + 2*(ts_offset_0.y)(t_vel.y)) - 2*(b_travel_dist_0)(b_speed)
c = (ts_offset_0.x)^2 + (ts_offset_0.y)^2 - (b_travel_dist_0)^2

Wait, I need to write these one other approach:

a = t_vel.dot(t_vel) - b_speed * b_speed
b = 2 * ts_offset_0.dot(t_vel) - 2 * b_travel_dist_0 * b_speed
c = ts_offset_0.dot(ts_offset_0) - b_travel_dist_0 * b_travel_dist_0

And we now have:

a * time^2 + b * time + c = 0

Allow us to lower to it, and use the quadratic system. Now we have two options:

time = (-b + sqrt(b^2 - 4ac))/2a

And

time = (-b - sqrt(b^2 - 4ac))/2a

We wish the smaller constructive one.


To recap we compute these beforehand:

b_travel_dist_0 = b_speed * time_0
ts_offset_0 = t_pos_0 - s_pos

Then these:

a = t_vel.dot(t_vel) - b_speed * b_speed
b = 2 * ts_offset_0.dot(t_vel) - 2 * b_travel_dist_0 * b_speed
c = ts_offset_0.dot(ts_offset_0) - b_travel_dist_0 * b_travel_dist_0

And eventually these:

instances = [
    (-b + sqrt(b^2 - 4ac))/2a,
    (-b - sqrt(b^2 - 4ac))/2a
]

That’s, in fact, riddled with pitfalls. Particularly division by zero and sq. root of damaging numbers.

That’s as a result of we’re searching for an answer when the shooter shoots at time zero. So the answer is easy: if computing that is invalid… Do not shoot. Skip the section. For those who attain the top of the trail, test once more subsequent body.

To ease computing the instances, I will do that as an alternative:

bb = b * b
a2 = 2 * a
ac4 = 4 * a * c

After which we are able to do that:

if bb >= ac4:
    r = sqrt(bb - ac4)
    instances = [
        (-b + r)/a2,
        (-b - r)/a2
    ]

Allow us to discover if there’s a legitimate time:

    time = INF
    for candidate_time in instances:
        if candidate_time < 0.0:
            proceed

        if candidate_time < time:
            time = candidate_time

    if not is_inf(time):
        move

You may compute the purpose to purpose merely like this:

t_pos_0 + t_vel * time

Alright, however we have to test whether it is inside this section, in any other case we now have to loop, proper? proper. So we do one thing like this:

t_index = index
whereas t_index + 1 < t_points.measurement():
    next_point = t_points[t_index + 1]
    t_vel = (next_point - t_pos_0).normalized() * t_speed
    time_to_next_point = (next_point - t_pos_0).size() / t_speed

    # OTHER STUFF SHOWN BEFORE GOES HERE

    if not is_inf(time):
        if time <= time_to_next_point:
            # INSERT SHOOT CODE HERE
            return

    time_0 += time_to_next_point
    t_pos_0 = next_point
    t_index += 1

Sure, I’ve examined this. In Godot with GDScript. Which is what I’ve been writing right here within the final elements of the reply. It isn’t Python, but it surely has very related syntax. So I hope it isn’t exhausting to adapt.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments