Advertisement
scroton

Untitled

Feb 25th, 2015
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.13 KB | None | 0 0
  1. function int ProjectileIntercept(int stid, int ttid, int spd, int ptid)
  2. {
  3. /* stid is the shooter tid, ttid is the target tid, spd is the speed of the projectile in fixed point, ptid is the tid the projectile will have */
  4.  
  5. int t, last_t, sml_t, n, diff, lastdiff, smldiff, check;
  6.  
  7. int a, b, c, t1, t2;
  8.  
  9. int sX = GetActorX(stid);
  10. int sY = GetActorY(stid);
  11. int sZ = GetActorZ(stid);
  12.  
  13. int tX = GetActorX(ttid);
  14. int tY = GetActorY(ttid);
  15. int tZ = GetActorZ(ttid);
  16.  
  17. //tZ = tZ + 26.5; This was just here for comparison with Thing_ProjectileIntercept, which fires above the target's Z approximately 26.5 map units.
  18.  
  19. int tVelX = GetActorVelX(ttid);
  20. int tVelY = GetActorVelY(ttid);
  21. int tVelZ = GetActorVelZ(ttid);
  22.  
  23. //Triangle STI, where S is shooter position, T is target position and I is where the target and fired projectile will intercept
  24.  
  25. int S_T_len = FixedSqrt(sq(sX - tX) + sq(sY - tY) + sq(sZ - tZ)); //Distance between shooter and target, or S_T
  26. int tVel_len = FixedSqrt(sq(tVelX) + sq(tVelY) + sq(tVelZ)); //Vector length for the shooter's velocity
  27.  
  28. int alg_dot_STI = FixedMul(sX-tX, tVelX) + FixedMul(sY-tY, tVelY) + FixedMul(sZ-tZ, tVelZ); /* The algebraic dot product, which is:
  29. //log(s: "alg_dot_STI:", f: alg_dot_STI);
  30.  
  31. http://en.wikipedia.org/wiki/Dot_product
  32. http://math.oregonstate.edu/home/programs/undergrad/CalculusQuestStudyGuides/vcalc/dotprod/dotprod.html
  33.  
  34. Vector0 * Vector1 =
  35. [x0,y0,z0] * [x1,y1,z1] =
  36. (x0 * x1) + (y0 * y1) + (z0 * z1)
  37.  
  38. which is equal to the geometric dot product, which is:
  39.  
  40. Vector0 * Vector1 =
  41. |V0| * |V1| * cos(θ) where θ is the angle between the vectors and |x| denotes "length of x"
  42.  
  43. so
  44.  
  45. sqrt(x0*x0 + y0*y0 + z0*z0) * sqrt(x1*x1 + y1*y1 + z1*z1) * cos(θ) = (x0 * x1 ) + (y0 * y1) + (z0 * z1)
  46.  
  47. so
  48.  
  49. cos(θ) = [(x0 * x1 ) + (y0 * y1) + (z0 * z1)] / [sqrt(x0*x0 + y0*y0 + z0*z0) * sqrt(x1*x1 + y1*y1 + z1*z1)]
  50.  
  51. */
  52.  
  53. int cos_STI = FixedDiv(alg_dot_STI, FixedMul(S_T_len, tVel_len));
  54.  
  55. /*
  56. Then using the Law of Cosines, which is:
  57.  
  58. c*c = a*a + b*b - 2*a*b*cos(C), where a, b, and c are sides of a triangle and C is the angle opposite side c.
  59.  
  60. in this case
  61.  
  62. a = S_T = S_T_len | S_T_len = FixedSqrt(sq(sX - tX) + sq(sY - tY) + sq(sZ - tZ));
  63.  
  64. b = T_I = target veloctiy * t = tVel_len * t | tVel_len = FixedSqrt(sq(tVelX) + sq(tVelY) + sq(tVelZ));
  65.  
  66. c = S_I = projectile veloctiy * t = spd * t | function argument
  67.  
  68. C = angle S_T_I = arccos(cos_STI) | cos_STI = FixedDiv(alg_dot_STI, FixedMul(S_T_len, tVel_len));
  69.  
  70. where t is time to impact, in tics.
  71.  
  72. We can then substitute
  73.  
  74. c*c = a*a + b*b - 2*a*b*cos(C)
  75.  
  76. (spd * t)*(spd * t) = (S_T_len)*(S_T_len) + (tVel_len * t)*(tVel_len * t) - 2*(S_T_len)*(tVel_len * t)*(cos_STI)
  77.  
  78. set it equal to zero by subtracting from the left
  79.  
  80. 0 = (S_T_len)*(S_T_len) + (tVel_len * t)*(tVel_len * t) - 2*(S_T_len)*(tVel_len * t)*(cos_STI) - (spd * t)*(spd * t)
  81.  
  82. then factor for t
  83.  
  84. 0 = (tVel_len * t)*(tVel_len * t) - (spd * t)*(spd * t) + (S_T_len)*(S_T_len) - 2*(S_T_len)*(tVel_len * t)*(cos_STI)
  85.  
  86. 0 = (tVel_len * t)*(tVel_len * t) - (spd * t)*(spd * t) + (S_T_len)*(S_T_len) - 2*(S_T_len)*(tVel_len * t)*(cos_STI)
  87.  
  88. 0 = (t*t)*(tVel_len)*(tVel_len) - (t*t)*(spd)*(spd) - (t)*2*(S_T_len)*(tVel_len)*(cos_STI) + (S_T_len)*(S_T_len)
  89.  
  90. 0 = (t^2)*((tVel_len)*(tVel_len) - (spd)*(spd)) + (t)*(-2*(S_T_len)*(tVel_len)*(cos_STI)) + (S_T_len)*(S_T_len)
  91.  
  92. since the expression is now in the form
  93.  
  94. y = ax^2 + bx + c = 0
  95.  
  96. we can use the quadratic formula
  97.  
  98. [-b +/- sqrt(b^2 - 4*a*c)] / (2*a)
  99.  
  100. to find when the two paths intersect
  101.  
  102. to make it easier, isolate a, b, and c from the expression
  103.  
  104. 0 = (t^2)*((tVel_len)*(tVel_len) - (spd)*(spd)) + (t)*(-2*(S_T_len)*(tVel_len)*(cos_STI)) + (S_T_len)*(S_T_len)
  105.  
  106. a = (tVel_len)*(tVel_len) - (spd)*(spd)
  107.  
  108. b = -2*(S_T_len)*(tVel_len)*(cos_STI)
  109.  
  110. c = (S_T_len)*(S_T_len)
  111.  
  112. */
  113.  
  114. a = sq(tVel_len) - sq(spd);
  115. b = -2 * FixedMul(FixedMul(S_T_len, tVel_len), cos_STI);
  116. c = sq(S_T_len);
  117.  
  118. t1 = FixedDiv( (-b + FixedSqrt(sq(b) - (4 * FixedMul(a,c)))) , (2 * a) );
  119.  
  120. t2 = FixedDiv( (-b - FixedSqrt(sq(b) - (4 * FixedMul(a,c)))) , (2 * a) );
  121.  
  122. log(s: "t1 = ", f: t1);
  123. log(s: "t2 = ", f: t2);
  124.  
  125. /* in this case only positive values for t can be used, so */
  126.  
  127. if(t1 > t2 && t1 > 0){ t = t1; }
  128. else if (t2 > 0){ t = t2; }
  129. else{ t = 99.0; }
  130.  
  131. log(s: "t = ", f: t);
  132.  
  133. int tVelX_t = FixedMul(t,tVelX);
  134. int tVelY_t = FixedMul(t,tVelY);
  135. int tVelZ_t = FixedMul(t,tVelZ);
  136. int tXf = tX + tVelX_t;
  137. int tYf = tY + tVelY_t;
  138. int tZf = tZ + tVelZ_t;
  139.  
  140. int Z_spd = FixedDiv(tZf - sZ, t);
  141. int X_spd = FixedDiv(tXf - sX, t);
  142. int Y_spd = FixedDiv(tYf - sY, t);
  143.  
  144. /* below is only used to have the firing actor be the firer of the projectile
  145. and allow assigning of a tid to that projectile */
  146.  
  147. Thing_ProjectileIntercept (stid, 201, 0, ttid, ptid);
  148.  
  149. SetActorAngle(ptid,VectorAngle(tXf - sX, tYf - sY));
  150. SetActorVelocity(ptid,X_spd,Y_spd,Z_spd,0,0);
  151.  
  152. return t;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement