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)