Advertisement
eruaaaaaaa

Untitled

May 15th, 2022
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.42 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. print(u)
  125. u = (isZero(u) and 0) or (u > 0 and math.sqrt(u)) or nil
  126. v = (isZero(v) and 0) or (v > 0 and math.sqrt(v)) or nil
  127.  
  128. if u == nil or v == nil then return 0 end
  129.  
  130. h = 1
  131. j = q < 0 and -v or v
  132. k = z - u
  133.  
  134. num = Polynomial.SolveQuadric(h, j, k, reftable)
  135.  
  136. j = -j
  137. k = z + u
  138.  
  139. if num == 0 then
  140. num = num + Polynomial.SolveQuadric(h, j, k, reftable)
  141. elseif num == 1 then
  142. num = num + Polynomial.SolveQuadric(h, j, k, holder)
  143.  
  144. reftable[2] = holder[1]
  145. reftable[3] = holder[2]
  146. elseif num == 2 then
  147. num = num + Polynomial.SolveQuadric(h, j, k, holder)
  148.  
  149. reftable[3] = holder[1]
  150. reftable[4] = holder[2]
  151. end
  152. end
  153.  
  154. if num > 0 then reftable[1] = reftable[1] - sub end
  155. if num > 1 then reftable[2] = reftable[2] - sub end
  156. if num > 2 then reftable[3] = reftable[3] - sub end
  157. if num > 3 then reftable[4] = reftable[4] - sub end
  158.  
  159. return num
  160. end
  161.  
  162. return Polynomial
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement