utility.lua 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. local utility = {}
  2. local function vectorDet(x1,y1, x2,y2)
  3. return x1*y2 - y1*x2
  4. end
  5. local function vectorCross( V, W )
  6. return V.x*W.y - V.y*W.x
  7. end
  8. --[[function areColinear(p, q, r, eps)
  9. return math.abs(vectorDet(q.x-p.x, q.y-p.y, r.x-p.x,r.y-p.y)) <= (eps or 1e-32)
  10. end]]
  11. -- test wether a and b lie on the same side of the line c->d
  12. local function onSameSide(a,b, c,d)
  13. local px, py = d.x-c.x, d.y-c.y
  14. local l = vectorDet(px,py, a.x-c.x, a.y-c.y)
  15. local m = vectorDet(px,py, b.x-c.x, b.y-c.y)
  16. return l*m >= 0
  17. end
  18. local function sign( v )
  19. return (v > 0 and 1) or (v < 0 and -1) or 0
  20. end
  21. -- Get which side of a line a point lies (-1, 0 or 1)
  22. function whichSideOfLine( l1,l2, p )
  23. --return sign( (Bx-Ax)*(Y-Ay) - (By-Ay)*(X-Ax) )
  24. return sign( (l1.x-l2.x)*(p.y-l1.y) - (l2.y-l1.y)*(p.x-l1.x) )
  25. end
  26. function projectPointOntoLine( l1,l2, p )
  27. -- Direction vector of line:
  28. local u = { x = l2.x - l1.x, y = l2.y - l1.y }
  29. -- Perpendicular to that:
  30. local n = { x =-u.y, y = u.x }
  31. local v = { x = p.x - l1.x, y = p.y - l1.y }
  32. local dist = vectorDot( u, v )/vectorDot( u, u )
  33. return { x=u.x*dist + l1.x, y = u.y*dist + l1.y }
  34. end
  35. function utility.linePointDist( l1,l2, p )
  36. local o = projectPointOntoLine( l1,l2, p )
  37. return utility.dist( o, p )
  38. end
  39. function utility.triangleArea( t )
  40. local p = projectPointOntoLine( t[1],t[2], t[3] )
  41. local width = utility.dist( t[1], t[2] )
  42. local height = utility.dist( t[3], p )
  43. return 0.5*width*height
  44. end
  45. function utility.pointInTriangle(p, a,b,c)
  46. return onSameSide(p,a, b,c) and onSameSide(p,b, a,c) and onSameSide(p,c, a,b)
  47. end
  48. function vectorDot( q, p )
  49. return q.x*p.x + q.y*p.y
  50. end
  51. function utility.printTable( t, depth )
  52. depth = depth or 1
  53. for k, v in pairs( t ) do
  54. if type(v) == "table" then
  55. print( string.rep( "\t", depth ) .. k .. " = {")
  56. utility.printTable( v, depth + 1 )
  57. print( string.rep( "\t", depth ) .. "}" )
  58. else
  59. print( string.rep( "\t", depth ) .. k .. " = ", v )
  60. end
  61. end
  62. end
  63. function utility.tablelength(T)
  64. local count = 0
  65. for _ in pairs(T) do count = count + 1 end
  66. return count
  67. end
  68. function utility.dist( p1, p2 )
  69. local dx = p1.x - p2.x
  70. local dy = p1.y - p2.y
  71. return math.sqrt( dx*dx + dy*dy )
  72. end
  73. function utility.length( p )
  74. return math.sqrt( p.x*p.x + p.y*p.y )
  75. end
  76. function utility.normalize( p )
  77. local len = utility.length( p )
  78. if len > 0 then
  79. return {x = p.x/len, y = p.y/len}
  80. else return p
  81. end
  82. end
  83. function utility.interpolateCos ( rel)
  84. return -math.cos(math.pi*rel)*0.5 + 0.5
  85. end
  86. function utility.segSegIntersection( seg1, seg2 )
  87. --local t = (q - p) x s /( r x s)
  88. local r = {x = seg2.p2.x - seg2.p1.x, y = seg2.p2.y - seg2.p1.y }
  89. local s = {x = seg1.p2.x - seg1.p1.x, y = seg1.p2.y - seg1.p1.y }
  90. local denom1 = vectorCross( r, s )
  91. local denom2 = vectorCross( s, r )
  92. if denom1 == 0 or denom2 == 0 then
  93. return false
  94. end
  95. local diff1 = { x = seg1.p1.x - seg2.p1.x, y = seg1.p1.y - seg2.p1.y }
  96. local diff2 = { x = seg2.p1.x - seg1.p1.x, y = seg2.p1.y - seg1.p1.y }
  97. local numer1 = vectorCross( diff1, s )
  98. local numer2 = vectorCross( diff2, r )
  99. local t = numer1/denom1
  100. if t < 0 or t > 1 then
  101. return false
  102. end
  103. local u = numer2/denom2
  104. if u < 0 or u > 1 then
  105. return false
  106. end
  107. return true, t, u
  108. end
  109. function utility.numFromString( str )
  110. local num = 0
  111. for k = 1, #str do
  112. num = num + string.byte( str:sub(k,k) )
  113. end
  114. return num
  115. end
  116. function utility.log( str, filename )
  117. filename = filename or "log.txt"
  118. ok, file = pcall( io.open, filename, "a" )
  119. if file then
  120. file:write( str .. "\n" )
  121. file:close()
  122. end
  123. end
  124. serverInfo = {
  125. numPlayers = 0,
  126. map = "-",
  127. state = "Lobby",
  128. }
  129. function utility.createServerInfo()
  130. local str = "Name:" .. SERVER_NAME .. ","
  131. str = str .. "Map:" .. serverInfo.map .. ","
  132. str = str .. "Players:" .. serverInfo.numPlayers .. "/" .. MAX_PLAYERS .. ","
  133. str = str .. "State:" .. serverInfo.state
  134. str = str:gsub("%s", "_")
  135. return str
  136. end
  137. function utility.rotatePoint( x, y, ang )
  138. return x*math.cos(ang) - y*math.sin(ang), x*math.sin(ang) + y*math.cos(ang)
  139. end
  140. return utility