Log In  6  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?

P#10277 2015-04-28 09:57 ( Edited 2016-07-01 16:51)  You'll probably have to write your own sqrt() function. I've seen it done in other people's carts.

P#10280 2015-04-28 12:12 ( Edited 2015-04-28 16:12)
:: viza  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. :(

P#10283 2015-04-28 12:47 ( Edited 2015-04-28 16:47)  It was in PAT Shooter, I believe.

P#10286 2015-04-28 17:02 ( Edited 2015-04-28 21:02)
:: zep  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 ```
P#10287 2015-04-28 17:10 ( Edited 2015-04-28 21:10)  +1 for both sqrt and atan2

P#10301 2015-04-28 20:45 ( Edited 2015-04-29 00:45)
:: viza  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.

P#10306 2015-04-29 03:42 ( Edited 2015-04-29 07:42)
:: jpfed  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)) ```

.

P#24105 2016-07-01 11:52 ( Edited 2016-07-01 15:52)
:: Danjen  I'm faving this thread just for the math tricks ... they're nice to know, even though the API supports this stuff now.

P#24115 2016-07-01 12:51 ( Edited 2016-07-01 16:51)