function setup()
ang=25
print(math.atan(ang))
print(math.atan(math.deg(ang)))
print(math.atan(math.rad(ang)))
print(math.atan2(ang))
print(math.atan2(math.deg(ang)))
print(math.atan2(math.rad(ang)))
end

math.atan(y/x) returns the angle from 0 to pi of the line with gradient y/x, so (x,y) and (-x,-y) return the same angle.

math.atan2(y,x) returns the angle from -pi to pi of the ray through the point (x,y) so (x,y) and (-x,-y) return angles that differ by pi. (Note the order of the arguments is y,x.)

@dave1707 - thanks for the feedback, tried using them and slight improvement with the following line of code :

angle = math.deg(math.atan(dy,dx))

Didn't produce the effect I wanted - now beginning to think it is language problem javascript to Lua. Just trying to duplicate some demo code and my Javascript is a little rusty - but I think it represents angles in a different form to Lua. Now investigating this. Will most what I am doing once I resolve it.

@LoopSpace - thanks for the feedback that's the best definition I've seen so far and fits what I am trying to do.

p.s. Is atan2() in the reference section for Lua in the Codea reference? Didn't see it.

@Bri_G If you describe what you're trying to do, I can advise better on which to use (though the answer is most likely to be atan2). I know a little javascript so if you post the original code, I may be able to help translate it. The atan/atan2 issue is different to radians vs degrees, but it may be that the latter is muddying the waters a bit (Codea isn't consistent on when it uses degrees and when radians).

OK, I'll post my code - it's trying to duplicate an example which I think is Javascript as it runs in a `PC window. My Codea post is below and the link to the demo is below it. I was hoping to use this to enable drawing of random strings on the screen - like scribbling across the screen, so I was interested in the curve and linking code to see if I could reproduce and modify to my needs:

displayMode(FULLSCREEN)
function setup()
--
parameter.watch("xpos[1]")
parameter.watch("ypos[1]")
parameter.watch("xpos[19]")
parameter.watch("ypos[19]")
parameter.watch("angle")
xpos = {} -- 20
ypos = {} -- 20
for loop = 1, 20, 1 do
xpos[loop] = 0
ypos[loop] = 0
end
segLength = 32
angle = 0
xin, yin = 0,0
skip = false
end
function draw()
background(0)
dragSegment(1,xin,yin)
if not skip then
for i = 1, #xpos-1, 1 do
dragSegment(i, xpos[i], ypos[i])
end
end
end
function touched(t)
--
if t.state == BEGAN then
xin,yin = t.x, t.y
skip = true
elseif t.state == MOVING then
xin,yin = t.x, t.y
skip = true
elseif t.state == ENDED then
xin,yin = 0,0
skip = true
end
end
function dragSegment(sn, xin, yin)
--
dx = xin - xpos[sn]
dy = yin - ypos[sn]
angle = math.atan2(dy, dx)
xpos[sn] = xin - math.cos(angle) * segLength
ypos[sn] = yin - math.sin(angle) * segLength
segment(xpos[sn], ypos[sn], angle)
end
function segment( x, y, a)
--
pushMatrix()
strokeWidth(9)
stroke(140, 143, 160, 100)
translate(x, y)
rotate(a)
line(0, 0, segLength, 0)
popMatrix()
end

@dave1707 In lua5.3 it seems that they've made a very sensible decision regarding math.atan and math.atan2:

math.atan (y [, x])

Returns the arc tangent of y/x (in radians), but uses the signs of both arguments to find the quadrant of the result. (It also handles correctly the case of x being zero.)

The default value for x is 1, so that the call math.atan(y) returns the arc tangent of y.

I'm presuming that @Simeon has made math.atan2 an alias of math.atan for backwards compatibility.

So math.atan() with a single argument computes the inverse tangent of its argument, while math.atan() with two arguments takes into account the quadrant.

This means that the crucial difference between the two is in the number of arguments that are supplied.

@LoopSpace - no problem with that but an entry in the reference reflecting this would be useful and highlight the importance of the number of parameters.

Calculating the inverse tangent is expensive, computationally speaking, and if you're only going to take its cosine and sine afterwards then there's no need. Normalising a vector is much cheaper.

@dave1707@LoopSpace - my code above tries to imitate Follow3.html - I have a number of parameters set up to view a few of the variables involved some seem to change rapidly whilst others don't appear to change suggesting I haven't got the correct logic. Also each segment is either overwriting the previous one or is not drawn at all and the vertical y properties seem to be ignored with the exception of the touch position.

The answer is probably very simple and obvious - but at the moment I can not see it.

@Bri_G Try this. The simple answer was that angle expects to be in degrees but all the atan2 values are in radians. Multiplying the angle by 180/pi converts radians to degrees.

displayMode(FULLSCREEN)
function setup()
x,y={},{}
for z=1,20 do
x[z]=0
y[z]=0
end
segLength = 18
strokeWidth(9);
stroke(255, 100);
tx,ty=0,0
end
function draw()
background(0);
dragSegment(1, tx, ty);
for i=1,#x-1 do
dragSegment(i+1, x[i], y[i]);
end
end
function touched(t)
if t.state==BEGAN or t.state==MOVING then
tx=t.x
ty=t.y
end
end
function dragSegment(i,xin,yin)
dx = xin - x[i]
dy = yin - y[i];
angle = math.atan2(dy, dx)
x[i] = xin - math.cos(angle) * segLength;
y[i] = yin - math.sin(angle) * segLength;
segment(x[i], y[i], angle);
end
function segment(x,y,a)
pushMatrix()
translate(x,y)
rotate(a*180/math.pi)
line(0,0,segLength,0)
popMatrix()
end

@Bri_G After I got your example working and I was playing with it, I thought it looked familar. I looked thru my code and found this. I’ll see if I can find when I first posted this. It must have been early in my coding years because I have displayMode inside of setup. I did that in my earlier years of Codea. Now I put it before setup.

--snake1
function setup()
displayMode(FULLSCREEN)
tab={}
x=WIDTH/2
y=HEIGHT/2
sx=0
sy=0
length=150
end
function draw()
background(40,40,50)
fill(255,0,0)
text("Drag your finger around the screen",WIDTH/2,HEIGHT-50)
x = x + sx
y = y + sy
if #tab<length then
table.insert(tab,1,vec2(x,y))
else
table.insert(tab,1,vec2(x,y))
table.remove(tab,#tab)
end
for a,b in pairs(tab) do
if a==1 then
ellipse(b.x,b.y,20,20)
else
ellipse(b.x,b.y,10,10)
end
end
end
function getDirection()
dx=CurrentTouch.x-x
dy=CurrentTouch.y-y
h=math.sqrt(dx*dx+dy*dy)
sx=dx/100
sy=dy/100
end
function touched(t)
getDirection()
end

@dave1707 - thanks for the correction, interesting how such a subtle change can make or break it. Thought it was down to format initially but struggled to resolve.

Also interesting that code with a terminal ; on lines is accepted?

## Comments

@Bri_G Does one of there work for you.

@Bri_G Or something like this.

`math.atan(y/x)`

returns the angle from 0 to pi of the line with gradient`y/x`

, so`(x,y)`

and`(-x,-y)`

return the same angle.`math.atan2(y,x)`

returns the angle from -pi to pi of the ray through the point`(x,y)`

so`(x,y)`

and`(-x,-y)`

return angles that differ by pi. (Note the order of the arguments is`y,x`

.)@dave1707 - thanks for the feedback, tried using them and slight improvement with the following line of code :

Didn't produce the effect I wanted - now beginning to think it is language problem javascript to Lua. Just trying to duplicate some demo code and my Javascript is a little rusty - but I think it represents angles in a different form to Lua. Now investigating this. Will most what I am doing once I resolve it.

@LoopSpace - thanks for the feedback that's the best definition I've seen so far and fits what I am trying to do.

p.s. Is atan2() in the reference section for Lua in the Codea reference? Didn't see it.

@Bri_G If you describe what you're trying to do, I can advise better on which to use (though the answer is most likely to be

`atan2`

). I know a little javascript so if you post the original code, I may be able to help translate it. The`atan`

/`atan2`

issue is different to radians vs degrees, but it may be that the latter is muddying the waters a bit (Codea isn't consistent on when it uses degrees and when radians).@Bri_G Run this. I don’t see a difference between atan and atan2.

@dave1707 - would you expect that?

OK, I'll post my code - it's trying to duplicate an example which I think is Javascript as it runs in a `PC window. My Codea post is below and the link to the demo is below it. I was hoping to use this to enable drawing of random strings on the screen - like scribbling across the screen, so I was interested in the curve and linking code to see if I could reproduce and modify to my needs:

and here is the link -

follow3

@dave1707 In lua5.3 it seems that they've made a very sensible decision regarding

`math.atan`

and`math.atan2`

:(source https://www.lua.org/manual/5.3/manual.html#pdf-math.atan )

I'm presuming that @Simeon has made

`math.atan2`

an alias of`math.atan`

for backwards compatibility.So

`math.atan()`

with a single argument computes the inverse tangent of its argument, while`math.atan()`

with two arguments takes into account the quadrant.This means that the crucial difference between the two is in the number of arguments that are supplied.

@LoopSpace - no problem with that but an entry in the reference reflecting this would be useful and highlight the importance of the number of parameters.

@Bri_G Point taken on the reference. Tagging @Simeon on this.

With regard to your code, I recommand that you replace:

with

Calculating the inverse tangent is expensive, computationally speaking, and if you're only going to take its cosine and sine afterwards then there's no need. Normalising a vector is much cheaper.

@dave1707 @LoopSpace - my code above tries to imitate Follow3.html - I have a number of parameters set up to view a few of the variables involved some seem to change rapidly whilst others don't appear to change suggesting I haven't got the correct logic. Also each segment is either overwriting the previous one or is not drawn at all and the vertical y properties seem to be ignored with the exception of the touch position.

The answer is probably very simple and obvious - but at the moment I can not see it.

@Bri_G Try this. The simple answer was that angle expects to be in degrees but all the atan2 values are in radians. Multiplying the angle by 180/pi converts radians to degrees.

@Bri_G After I got your example working and I was playing with it, I thought it looked familar. I looked thru my code and found this. I’ll see if I can find when I first posted this. It must have been early in my coding years because I have displayMode inside of setup. I did that in my earlier years of Codea. Now I put it before setup.

@dave1707 - thanks for the correction, interesting how such a subtle change can make or break it. Thought it was down to format initially but struggled to resolve.

Also interesting that code with a terminal ; on lines is accepted?

Thanks again