Advertisement
eruaaaaaaa

Poly

May 14th, 2022 (edited)
1,136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.41 KB | None | 0 0
  1. --//Port of http://www.realtimerendering.com/resources/GraphicsGems/gems/Roots3And4.c from Graphics Gems
  2.  
  3. local Polynomial = {}
  4.  
  5. local math = math
  6. local zero = 1e-30
  7.  
  8. local onethird = 1/3
  9. local twotwsevs = 2/27
  10. local threetwohund = 3/256
  11. local onesixteenth = 1/16
  12. local oneeighth = .125
  13. local threeeighths = .375
  14. local onehalf = 0.5
  15. local onefourth = 0.25
  16.  
  17. local thirdpi = math.pi / 3
  18.  
  19. local function isZero(num)
  20. return num < zero and num > -zero
  21. end
  22.  
  23. local function cubicRoot(num)
  24. return (num > 0 and math.pow(num, onethird)) or (num < 0 and -math.pow(-num, onethird)) or 0
  25. end
  26.  
  27. function Polynomial.SolveQuadric(c0, c1, c2, reftable)
  28. local p, q, D
  29.  
  30. p = c1 / (2 * c0)
  31. q = c2 / c0
  32.  
  33. D = p * p - q
  34.  
  35. if isZero(D) then
  36. reftable[1] = -p
  37. return 1
  38. elseif D < 0 then
  39. return 0
  40. else
  41. local sqr = math.sqrt(D)
  42.  
  43. reftable[1] = sqr - p
  44. reftable[2] = -sqr - p
  45.  
  46. return 2
  47. end
  48. end
  49.  
  50. function Polynomial.SolveCubic(c0, c1, c2, c3, reftable)
  51. local num, sub, A, B, C, sqA, p, q, cbp, D
  52.  
  53. A = c1 / c0
  54. B = c2 / c0
  55. C = c3 / c0
  56.  
  57. sqA = A * A
  58. p = onethird * (-onethird * sqA + B)
  59. q = onehalf * (twotwsevs * A * sqA - onethird * A * B + C)
  60.  
  61. cbp = p * p * p
  62. D = q * q + cbp
  63.  
  64. sub = onethird * A
  65.  
  66. if isZero(D) then
  67. if isZero(q) then
  68. reftable[1] = 0 - sub
  69. num = 1
  70. else
  71. local u = cubicRoot(-q)
  72.  
  73. reftable[1] = 2 * u - sub
  74. reftable[2] = -u - sub
  75.  
  76. num = 2
  77. end
  78. elseif D < 0 then
  79. local phi = onethird * math.acos(-q / math.sqrt(-cbp))
  80. local t = 2 * math.sqrt(-p)
  81.  
  82. reftable[1] = t * math.cos(phi) - sub
  83. reftable[2] = -t * math.cos(phi + thirdpi) - sub
  84. reftable[3] = -t * math.cos(phi - thirdpi) - sub
  85.  
  86. num = 3
  87. else
  88. local sqrD = math.sqrt(D)
  89.  
  90. reftable[1] = cubicRoot(sqrD - q) - cubicRoot(sqrD + q) - sub
  91. num = 1
  92. end
  93.  
  94. return num
  95. end
  96.  
  97. function Polynomial.SolveQuartic(c0, c1, c2, c3, c4, reftable)
  98. local num, z, u, v, sub, A, B, C, D, sqA, p, q, r
  99.  
  100. A = c1 / c0
  101. B = c2 / c0
  102. C = c3 / c0
  103. D = c4 / c0
  104.  
  105. sqA = A * A
  106. p = -threeeighths * sqA + B
  107. q = oneeighth * sqA * A - onehalf * A * B + C
  108. r = -threetwohund * sqA * sqA + onesixteenth * sqA * B - onefourth * A * C + D
  109.  
  110. sub = onefourth * A
  111.  
  112. if isZero(r) then
  113. num = Polynomial.SolveCubic(1, 0, p, q, reftable)
  114. else
  115. local holder = {}
  116. local h, j, k
  117.  
  118. Polynomial.SolveCubic(1, -onehalf * p, -r, onehalf * r * p - oneeighth * q * q, reftable)
  119. z = reftable[1]
  120.  
  121. u = z * z - r
  122. v = 2 * z - p
  123.  
  124. u = (isZero(u) and 0) or (u > 0 and math.sqrt(u)) or nil
  125. v = (isZero(v) and 0) or (v > 0 and math.sqrt(v)) or nil
  126.  
  127. if u == nil or v == nil then return 0 end
  128.  
  129. h = 1
  130. j = q < 0 and -v or v
  131. k = z - u
  132.  
  133. num = Polynomial.SolveQuadric(h, j, k, reftable)
  134.  
  135. j = -j
  136. k = z + u
  137.  
  138. if num == 0 then
  139. num = num + Polynomial.SolveQuadric(h, j, k, reftable)
  140. elseif num == 1 then
  141. num = num + Polynomial.SolveQuadric(h, j, k, holder)
  142.  
  143. reftable[2] = holder[1]
  144. reftable[3] = holder[2]
  145. elseif num == 2 then
  146. num = num + Polynomial.SolveQuadric(h, j, k, holder)
  147.  
  148. reftable[3] = holder[1]
  149. reftable[4] = holder[2]
  150. end
  151. end
  152.  
  153. if num > 0 then reftable[1] = reftable[1] - sub end
  154. if num > 1 then reftable[2] = reftable[2] - sub end
  155. if num > 2 then reftable[3] = reftable[3] - sub end
  156. if num > 3 then reftable[4] = reftable[4] - sub end
  157.  
  158. return num
  159. end
  160.  
  161. return Polynomial
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement