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?

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)

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)

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)

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)

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)

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)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 12:17:49 | 0.009s | Q:22