# Snippet - Sin/Cos functions

This will be helpful to some. I make helper functions to estimate sin and cos functions. I used Taylor series to estimate. Here's an example drawing a dot at the position of the crank:

``````on draw do
// Draw a crank dot
if event.ra!=0 then
a = event.aa
a /= 180
a *= 3.14159
emit "sin"
emit "cos"
x = sin
x *= 32
x += 32
x += 2

y = cos
y *= 32
y += 32
y += 2
end
fill "white" at x,y,4,4
end
``````

Put this in the game script:

``````
on sin do
aNorm = a
while aNorm>=3.141592 do
aNorm -= 6.283184
end

n = 0
modifier = 1
sin = 0
while n<6 do
// modifier * aNorm^(2n+1)
// -------------------
// (2n+1)!
pow = n
pow *= 2
pow += 1

// numerator
num = modifier
p = pow
while p>0 do
num *= aNorm
p--
end

// denominator
f = pow
den = 1
while f>0 do
den *= f
f--
end
if den==0 then
den = 1
end

// log "{modifier} * {num}"
// log "------------------"
// log "{den}"

num /= den
sin += num

// Set up next loop
modifier *= -1
n += 1
end
end

on cos do
oldA = a
oldSin = sin
a += 1.57079
call "sin"
cos = sin
cos *= -1 // Trig is y up, pulp is y down
a = oldA
sin = oldSin
end

``````

the `n < 6` is the number of iterations, and I've found 6 is good enough for three decimal places.

Edit: There were some issues when the number was > pi, which I fixed by limiting the angle from -pi to pi.

5 Likes

This is great! I have a couple of questions:

How would we change where on the screen the crank dot appears?

Is it possible to use this function to move the player?

How would we change where on the screen the crank dot appears?

The first snippet shows how to position the dot around a point, but doesn't explicitly say it.

``````on draw do
// Draw a crank dot
if event.ra!=0 then
a = event.aa
a /= 180
a *= 3.14159
emit "sin"
emit "cos"
x = sin
x *= 32 // Scale the radius 32 pixels wide
x += 32 // Move the center point 32 pixels to the right
x += 2

y = cos
y *= 32 // Scale the radius 32 pixels tall
y += 32 // Move the center 32 pixels down
y += 2
end
fill "white" at x,y,4,4
end
``````
1 Like

Yes, you could do your math to find where the x and y are, then divide each by 8 to convert to tile coordinates. Then use the `goto` function to send the player there.

``````x /= 8
x = floor x
y /= 8
y = floor y

goto x,y
``````

Beware it might not be happy with you using the `goto` function in the `draw` event, so you might want to do the math in a regular event if this is your intended action.

1 Like

Bit shaky but that works! I'll fiddle around with it as I go, but thanks very much for the help, this may have solved the problem I've been tussling with all day.

Instead of using `emit` to call these functions I would use `tell event.game` and `call`. `emit` has to ask the game, current room, player, and all 375 tiles in the current room if they handle the emitted event. That’s a lot more overhead than directly `tell`-ing the single object you already know implements the event handler. (And that overhead is only being compounded by calling it 20 frames per second in the `draw` event handler. I would move the sin/cos calculations and setting of x,y to the player’s `crank` event handler.)

1 Like

@BoldBigflank A short followup: I’ve added native `sine` and `cosine` functions to PulpScript (plus `tangent`, `radians`, and `degrees`). One thing I noticed is that your pure PulpScript event handler versions are returning inverted values. So when you switch from these (the native versions provide a huge performance boost, PulpScript wasn't built to be especially math-y ) you’ll want to invert the new return values with `*= -1`. The additions should be up sometime this week. (I’ll update this comment when the changes go live.)

4 Likes

Thanks, Shaun! Glad we're getting these functions built in.