fork(7) download
  1. import math
  2.  
  3. class Point:
  4. def __init__(self, x,y):
  5. self.x = x
  6. self.y = y
  7.  
  8. def magnitude(self):
  9. return math.sqrt(self.x*self.x + self.y*self.y)
  10.  
  11. def _applyVectorFunc(self, other, f):
  12. return Point(f(self.x, other.x), f(self.y, other.y))
  13. def _applyScalarFunc(self, a, f):
  14. return self._applyVectorFunc(Point(a,a), f)
  15.  
  16. def __add__(self, other):
  17. return self._applyVectorFunc(other, lambda a,b: a+b)
  18. def __sub__(self, other):
  19. return self._applyVectorFunc(other, lambda a,b: a-b)
  20. def __mul__(self, a):
  21. return self._applyScalarFunc(a, lambda b,c: b*c)
  22. def __div__(self, a):
  23. return self._applyScalarFunc(a, lambda b,c: b/c)
  24.  
  25. def __repr__(self):
  26. return "Point({}, {})".format(self.x, self.y)
  27.  
  28. def dot_product(a,b):
  29. return a.x * b.x + a.y * b.y
  30.  
  31. def angle_between(b,c):
  32. return math.acos(dot_product(b,c) / (b.magnitude() * c.magnitude()))
  33.  
  34. def to_degrees(a):
  35. return a * 360 / (2*math.pi)
  36.  
  37. def find_collision_point(target_pos, target_vel, interceptor_pos, interceptor_speed):
  38. k = target_vel.magnitude() / interceptor_speed
  39. c = (interceptor_pos - target_pos).magnitude()
  40.  
  41. b_hat = target_vel
  42. c_hat = interceptor_pos - target_pos
  43.  
  44. CAB = angle_between(b_hat, c_hat)
  45. ABC = math.asin(math.sin(CAB) * k)
  46. ACB = (math.pi) - (CAB + ABC)
  47.  
  48. j = c / math.sin(ACB)
  49. a = j * math.sin(CAB)
  50. b = j * math.sin(ABC)
  51.  
  52.  
  53. t = b / target_vel.magnitude()
  54. collision_pos = target_pos + (target_vel * t)
  55.  
  56. print "Collision pos: {}".format(collision_pos)
  57. print "Time: {}".format(t)
  58.  
  59. print "Angle A: {}".format(to_degrees(CAB))
  60. print "Angle B: {}".format(to_degrees(ABC))
  61. print "Angle C: {}".format(to_degrees(ACB))
  62.  
  63. print "a: {}".format(a)
  64. print "b: {}".format(b)
  65. print "c: {}".format(c)
  66.  
  67. target_pos = Point(120,40)
  68. target_vel = Point(5,2)
  69. interceptor_pos = Point(80,80)
  70. interceptor_speed = 10
  71.  
  72. find_collision_point(target_pos, target_vel, interceptor_pos, interceptor_speed)
Success #stdin #stdout 0.01s 7692KB
stdin
Standard input is empty
stdout
Collision pos: Point(163.065368246, 57.2261472985)
Time: 8.61307364926
Angle A: 113.198590514
Angle B: 29.6680851288
Angle C: 37.1333243575
a: 86.1307364926
b: 46.3828210973
c: 56.5685424949