Created
January 30, 2025 10:50
-
-
Save alexhunsley/38021a320fcceae39bba70e4c4daa083 to your computer and use it in GitHub Desktop.
Bad python code found on social media for intersection of objects. Don't do this!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
def perpendicular_interceptor(pO, vO, pI, speedI): | |
""" | |
Calculates an interceptor velocity that is perpendicular to vO and | |
finds the time of intercept, if it exists. | |
Parameters: | |
----------- | |
pO : tuple (xO, yO) | |
Target's initial position. | |
vO : tuple (vOx, vOy) | |
Target's velocity. | |
pI : tuple (xI, yI) | |
Interceptor's initial position. | |
speedI : float | |
The interceptor's desired speed. | |
Returns: | |
-------- | |
(vI, t) : (tuple, float) or (None, None) | |
vI is the interceptor's velocity vector (vx, vy). | |
t is the time at which the interceptor meets the target. | |
If no positive solution for t is found, (None, None) is returned. | |
""" | |
# 1. Construct a perpendicular vector to vO in 2D. | |
# A vector perpendicular to (vOx, vOy) can be (vOy, -vOx) or (-vOy, vOx). | |
vOx, vOy = vO | |
perp_vec = (vOy, -vOx) | |
print(perp_vec) | |
# 2. Normalize and scale by speedI to get the interceptor velocity. | |
# norm = sqrt(vOy^2 + (-vOx)^2) = sqrt(vOx^2 + vOy^2) | |
magnitude = math.sqrt(perp_vec[0]**2 + perp_vec[1]**2) | |
print(magnitude) | |
if magnitude == 0: | |
# If the target has no velocity, perpendicular isn't defined. | |
return (None, None) | |
factor = speedI / magnitude | |
vIx = perp_vec[0] * factor | |
vIy = perp_vec[1] * factor | |
# 3. Solve for intercept time. | |
# We need pO + vO*t = pI + vI*t => (vO - vI)*t = pI - pO | |
# We'll find t from x-component and y-component, then check if they match. | |
xO, yO = pO | |
xI, yI = pI | |
# Compute differences | |
dx = xI - xO | |
dy = yI - yO | |
# Differences in velocity | |
dvx = vOx - vIx | |
dvy = vOy - vIy | |
t_candidates = [] | |
# From x-component if dvx != 0 | |
if abs(dvx) > 1e-12: | |
tx = dx / dvx | |
t_candidates.append(tx) | |
# From y-component if dvy != 0 | |
if abs(dvy) > 1e-12: | |
ty = dy / dvy | |
t_candidates.append(ty) | |
# If both x and y gave us times, we need them to be "close" to each other. | |
# If only one gave a time, we use that. If neither did, there's no solution. | |
if len(t_candidates) == 0: | |
# Means the interceptor velocity exactly matches the target’s velocity in x and y, | |
# or the target is stationary. | |
return (None, None) | |
if len(t_candidates) == 1: | |
t = t_candidates[0] | |
else: | |
# We have two values: tx and ty. They must match within a small tolerance. | |
tx, ty = t_candidates | |
if abs(tx - ty) < 1e-9: | |
t = (tx + ty) / 2.0 # they are effectively the same | |
else: | |
return (None, None) | |
# We want a positive time for a future intercept. | |
if t < 0: | |
return (None, None) | |
# Return the interceptor velocity vector and time | |
return ((vIx, vIy), t) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment