Log In  


Is there a square root function somewhere in pico-8?
The lua sqrt doesn't seem to work, and there is no mention of such function in the docs either.

Or is there an easy way to calculate a unit vector?

6


You'll probably have to write your own sqrt() function. I've seen it done in other people's carts.


Do you happen to remember in which game did you see it?
I already look trough a number of them, but no luck so far. :(


It was in PAT Shooter, I believe.


Here's Benjamin's sqrt and atan2 from PAT Shooter:

function sqrt(n)
 local i = 0
 while(i*i <= n) do 
  i += 1
 end
 i -= 1
 local d = n-i*i
 local p = d/(2*i)
 local a = i+p
 return a -(p*p)/(2*a)
end

function atan2(dy,dx)
 local q = 0.125
 local a = 0
 local ay = abs(dy)
 if( ay == 0 ) ay = 0.001 
 if( dx >= 0 ) then
  local r = (dx-ay)/(dx+ay)
  a = q - r*q
 else
  local r = (dx+ay)/(ay-dx)
  a = q*3 - r*q
 end
 if( dy >  0 ) a = -a 
 return a
end

I'm trying to keep the api super-minimal, but I think it will be worth adding these 2 functions, especially as they normally use a lot of code space. So they might show up in 0.1.1 :)

Incidentally, if you ever need a rough approximation of a vector (dx, dy)'s magnitude, I often use:

max(abs(dx),abs(dy)) + min(abs(dx),abs(dy)) / 2

+1 for both sqrt and atan2


Thank you!

I mark the thread as "Solved" for future reference if anybody is looking for a solution for this until the functions made into the engine.


If you'd like to approximate vector magnitude, here's something that is actually pretty accurate (and of comparable token count to zep's expression):

abs(dx)+abs(dy)-0.585786*min(abs(dx),abs(dy))

How does it work? Imagine walking from one point to another and counting your steps. If you could only walk north, south, east, or west, the distance travelled would be

abs(dx)+abs(dy)

(called Manhattan distance). But if you could also take 45 degree steps (NE, NW, SE, SW), then as long as you can make progress in both x and y directions, you can take a step that's sqrt(2) in length instead of 2 orthogonal steps.

How many times can you take a diagonal step? Just

min(abs(dx),abs(dy))

. How much do you save by doing this, per diagonal step? 2-sqrt(2) = 0.585786. When you take into account your savings you get

abs(dx)+abs(dy)-0.585786*min(abs(dx),abs(dy))

.


I'm faving this thread just for the math tricks ... they're nice to know, even though the API supports this stuff now.



[Please log in to post a comment]