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?
You'll probably have to write your own sqrt() function. I've seen it done in other people's carts.
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 |
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)) |
.
[Please log in to post a comment]