Skip to content
Advertisement

Python: Setting the X and Y vectors of a bullet

I need to calculate the vector_x and vector_y of a bullet, fired from x1, y1. The target is at x2, y2.

vector_x describes the number of units the bullet travels in the x direction per second. vector_y describes the same, just with the y direction.

I tried many different versions of the same function, but I was unable to come up with a version that:

  • Keeps vector_x and vector_y between 0 and 1
  • The bullets hit the target (assuming inaccuracy is 0), no matter where the target is.
  • Inaccuracy has the same hit chance no matter where the target is relative to x1, x1.

x 0, y 0 is at the top left corner.

This is my best attempt so far:

def get_vectors(x1, y1, x2, y2, inaccuracy=0):
    x2 += random.randint(inaccuracy * -1, inaccuracy)
    y2 += random.randint(inaccuracy * -1, inaccuracy)

    x_dist = x2 - x1
    y_dist = y2 - y1

    dist = [x_dist, y_dist]


    if x_dist >= 0:
        if y_dist >= 0:  # BOTH POSITIVE
            vector_x = x_dist / max(dist, key=abs)
            vector_y = y_dist / max(dist, key=abs)
        else:  # X POSITIVE Y NEGATIVE
            vector_x = x_dist / max(dist, key=abs) * -1
            vector_y = y_dist / max(dist, key=abs) * -1
    else:
        if y_dist >= 0:  # X NEGATIVE Y POSITIVE
            vector_x = x_dist / max(dist, key=abs)
            vector_y = y_dist / max(dist, key=abs)
        else:  # BOTH NEGATIVE
            vector_x = x_dist / max(dist, key=abs) * -1
            vector_y = y_dist / max(dist, key=abs) * -1

    return vector_x, vector_y

While this works in some cases, it mostly fires in wrong directions. How can I fix this code?

Advertisement

Answer

A simple unit vector approach:

def get_vector(x1, y1, x2, y2) -> tuple[int, int]:
    
    # Vector v or difference
    v_x = x2 - x1
    v_y = y2 - y1
    
    # TODO: Add inaccuracy to v


    # lenght of v
    v_len = (v_x**2 + v_y**2)**0.5
    
    # unit vector u of v
    u_x = v_x / v_len
    u_y = v_y / v_len
    
    return (u_x, u_y)
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement