Advertisement
Guest User

Untitled

a guest
Apr 29th, 2017
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.81 KB | None | 0 0
  1. local function IsZero(a)
  2. return a<0.0001
  3. end
  4.  
  5. function SolveQuadric(c0, c1, c2)
  6. local s0 = 0
  7. local s1 = 0
  8.  
  9. local p, q, D;
  10.  
  11. p = c1 / (2 * c0);
  12. q = c2 / c0;
  13.  
  14. D = p * p - q;
  15.  
  16. if (IsZero(D)) then
  17. s0 = -p;
  18. return 1, s0, s1;
  19. elseif (D < 0) then
  20. return 0, s0, s1
  21. else
  22. local sqrt_D = math.sqrt(D);
  23.  
  24. s0 = sqrt_D - p;
  25. s1 = -sqrt_D - p;
  26. return 2, s0, s1
  27. end
  28. end
  29.  
  30. function SolveCubic(c0, c1, c2, c3)
  31. local s0 = 0
  32. local s1 = 0
  33. local s2 = 0
  34.  
  35. local num;
  36. local sub;
  37. local A, B, C;
  38. local sq_A, p, q;
  39. local cb_p, D;
  40.  
  41. --/* normal form: x^3 + Ax^2 + Bx + C = 0 */
  42. A = c1 / c0;
  43. B = c2 / c0;
  44. C = c3 / c0;
  45.  
  46. -- /* substitute x = y - A/3 to eliminate quadric term: x^3 +px + q = 0 */
  47. sq_A = A * A;
  48. p = 1.0/3 * (- 1.0/3 * sq_A + B);
  49. q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
  50.  
  51. --/* use Cardano's formula */
  52. cb_p = p * p * p;
  53. D = q * q + cb_p;
  54.  
  55. if (IsZero(D)) then
  56. if (IsZero(q)) then
  57. s0 = 0;
  58. num = 1;
  59. else
  60. local u = math.pow(-q, 1.0/3.0);
  61. s0 = 2 * u;
  62. s1 = - u;
  63. num = 2;
  64. end
  65. elseif (D < 0) then
  66. local phi = 1.0/3 * math.acos(-q / math.sqrt(-cb_p))
  67. local t = 2 * math.sqrt(-p);
  68.  
  69. s0 = t * math.cos(phi);
  70. s1 = - t * math.cos.Cos(phi + math.pi / 3)
  71. s2 = - t * math.cos.Cos(phi - math.pi / 3)
  72. num = 3;
  73. else --/* one real solution */ {
  74. local sqrt_D = math.sqrt(D);
  75. local u = math.pow(sqrt_D - q, 1.0/3.0)
  76. local v = - math.pow(sqrt_D + q, 1.0/3.0)
  77.  
  78. s0 = u + v;
  79. num = 1;
  80. end
  81.  
  82. sub = 1.0/3 * A;
  83.  
  84. if (num > 0) then s0 = s0-sub end
  85. if (num > 1) then s1 = s1-sub end
  86. if (num > 2) then s2 = s2-sub end
  87.  
  88. return num, s0, s1, s2
  89. end
  90.  
  91. function SolveQuartic(c0,c1,c2,c3,c4)
  92. local s0 = 0
  93. local s1 = 0
  94. local s2 = 0
  95. local s3 = 0
  96.  
  97. local coeffs = {}
  98. local z, u, v, sub
  99. local A, B, C, D
  100. local sq_A, p, q, r
  101. local num;
  102.  
  103. local A = c1 / c0;
  104. local B = c2 / c0;
  105. local C = c3 / c0;
  106. local D = c4 / c0;
  107.  
  108. local sq_A = A * A;
  109. local p = - 3.0/8 * sq_A + B;
  110. local q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C;
  111. local r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D;
  112.  
  113. if (r < 0.001) then
  114. coeffs[3] = q;
  115. coeffs[2] = p;
  116. coeffs[1] = 0;
  117. coeffs[0] = 1;
  118.  
  119. num, s0, s1, s3 = SolveCubic(coeffs[0], coeffs[1], coeffs[2], coeffs[3])
  120.  
  121. else
  122. coeffs[ 3 ] = 1.0/2 * r * p - 1.0/8 * q * q;
  123. coeffs[ 2 ] = - r;
  124. coeffs[ 1 ] = - 1.0/2 * p;
  125. coeffs[ 0 ] = 1;
  126.  
  127. num, s0, s1, s3 = SolveCubic(coeffs[0], coeffs[1], coeffs[2], coeffs[3])
  128.  
  129. z = s0;
  130.  
  131. u = z * z - r;
  132. v = 2 * z - p;
  133.  
  134. if (IsZero(u)) then
  135. u = 0
  136. elseif (u > 0) then
  137. u = math.sqrt(u)
  138. else
  139. return 0
  140. end
  141.  
  142. if (IsZero(v)) then
  143. v = 0;
  144. elseif (q > 0) then
  145. v = math.sqrt(v)
  146. else
  147. return 0;
  148. end
  149.  
  150. coeffs[ 2 ] = z - u
  151. if q < 0 then
  152. coeffs[ 1 ] = -v
  153. else
  154. coeffs[ 1 ] = v
  155. end
  156. coeffs[ 0 ] = 1;
  157.  
  158. num, s0, s1 = SolveQuadric(coeffs[0], coeffs[1], coeffs[2]);
  159.  
  160. coeffs[ 2 ]= z + u
  161. if q < 0 then
  162. coeffs[ 1 ] = v
  163. else
  164. coeffs[ 1 ] = -v
  165. end
  166. coeffs[ 0 ] = 1;
  167.  
  168.  
  169. if (num == 0) then
  170. local temp, s0, s1 = SolveQuadric(coeffs[0], coeffs[1], coeffs[2])
  171. num = num + temp
  172. end
  173. if (num == 1) then
  174. local temp, s1, s2 = SolveQuadric(coeffs[0], coeffs[1], coeffs[2])
  175. num = num + temp
  176. end
  177. if (num == 2) then
  178. local temp, s2, s3 = SolveQuadric(coeffs[0], coeffs[1], coeffs[2])
  179. num = num + temp
  180. end
  181. end
  182.  
  183. sub = 1.0/4 * A;
  184.  
  185. if (num > 0) then s0 = s0 - sub end
  186. if (num > 1) then s1 = s1 - sub end
  187. if (num > 2) then s2 = s2 - sub end
  188. if (num > 3) then s3 = s3 - sub end
  189.  
  190. return num, s0, s1, s2, s3
  191. end
  192.  
  193. local function Solve(x, z, target_velocity, proj_speed)
  194.  
  195. local G = 196.2
  196.  
  197. local A = x
  198. local B = 0
  199. local C = z
  200. local M = 0
  201. local N = 0
  202. local O = 0
  203. local P = target_velocity.x
  204. local Q = target_velocity.y
  205. local R = target_velocity.z
  206. local S = proj_speed
  207.  
  208. local H = M - A;
  209. local J = O - C;
  210. local K = N - B;
  211. local L = -.5 * G;
  212.  
  213. local c0 = L*L;
  214. local c1 = 2*Q*L;
  215. local c2 = Q*Q + 2*K*L - S*S + P*P + R*R;
  216. local c3 = 2*K*Q + 2*H*P + 2*J*R;
  217. local c4 = K*K + H*H + J*J;
  218.  
  219. local numTimes, t1, t2, t3, t4 = SolveQuartic(c0, c1, c2, c3, c4)
  220.  
  221. print(numTimes)
  222.  
  223. local solutions = {}
  224. local times = {t2, t3, t4}
  225. times[0] = t1
  226.  
  227. local numSolutions = 0
  228.  
  229. for i=0, 3 do
  230. local t = times[i]
  231. if t == nil then break end
  232. --if (t>0) == false then break end
  233. solutions[numSolutions] = Vector3.new(((H+P*t)/t), ((K+Q*t-L*t*t)/ t), ((J+R*t)/t))
  234. numSolutions = numSolutions + 1
  235. end
  236.  
  237. local s0, s1
  238.  
  239. if numSolutions > 0 then
  240. s0 = solutions[0]
  241. end
  242. if numSolutions > 0 then
  243. s1 = solutions[1]
  244. end
  245.  
  246. return numSolutions, s0, s1, solutions
  247.  
  248. end
  249.  
  250. return Solve
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement