Problem with atan2

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
VirusX
Prole
Posts: 5
Joined: Sat May 17, 2014 11:58 am

Problem with atan2

Post by VirusX »

I'm having bit of a problem with atan2. Scratching my head for last couple days and can't understand why it does not work.

I need simple lookAt() function which I found here in forums, but it works arseways for me ):

I have two actors. First actor1 should look at actor2. I also added two white lines: line1 actors r0 position and line2 where it should look at.
Screen Shot 2014-06-02 at 15.36.10.png
Screen Shot 2014-06-02 at 15.36.10.png (34.12 KiB) Viewed 4315 times
Code :

Code: Select all

actor1 = { x = 200, y = 200}
actor2 = { x = 500, y = 50}

function love.load()
	actorImg = love.graphics.newImage("actor.png") --64x64
	ox = actorImg:getWidth() / 2
	oy = actorImg:getHeight() / 2
end

function love.mousepressed( x, y, button )
	if button == 'l' then
		angle = lookAt(actor1, actor2)
		print(angle..' Deg: '..math.deg(angle))
	end
end

function lookAt(obj, target)
  local a = math.atan2(target.y - obj.y, target.x - obj.x)
  return a < 0 and a + math.pi * 2 or a
end

function love.draw()
	-- actor1
	love.graphics.draw(actorImg, actor1.x, actor1.y, angle, 1,1, ox, oy )
	-- actor2
	love.graphics.draw(actorImg, actor2.x, actor2.y, 0, 1,1, ox, oy)
	
	-- line1 r0 position
	love.graphics.line(actor1.x, actor1.y, actor2.x, actor2.y)
	-- line2 lookAt
	love.graphics.line(actor1.x, actor1.y, actor1.x, 0)
end
Also console output: 5.8195376981788 Deg: 333.43494882292

Not sure what I'm doing wrong, so any help more then welcome.
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Problem with atan2

Post by HugoBDesigner »

Oh, yeah, I ALWAYS have problems with math.atan2. The system of angles they use there is different. Here's what I mean:
shitty_math_atan2.png
shitty_math_atan2.png (16.65 KiB) Viewed 4304 times
I made this some time ago even. The way I found to work on this is to have a conversion function. You can use this, if you want:

Code: Select all

function convertAngle(a)
	local a = a
	a = math.pi-a
	return math.offset(math.abs(a)+math.pi/2, 0, math.pi*2, math.pi*2)
end
It may not work 100%, but where I used it it worked fine. I hope I helped!
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Problem with atan2

Post by Roland_Yonaba »

JUst wanted to point out something.
Love system coordinates is not the same as the one assumed in a classical euclidian space.
In LÖVE, x is positive and grows when moving right, and y is positive and grows when moving down. The center is the left-upper bottom of the screen. This is not odd, most of game frameworks uses the same convention.
But, in a euclidian space, the classical one taught at school, we often assume x is positive and grows when moving right, and y is positive and grows when moving up (as opposed to LÖVE's system of coordinates).
Therefore, I think flipping the dy sign in your function fixes everything.

Code: Select all

local function getAngleBetween(obj, target)
  local dx = target.x - obj.x
  local dy = -(target.y - obj.y) -- same as obj.y - target.y
  local rad = math.atan2(dy, dx)
  return rad < 0 and rad + math.pi*2 or rad
end
VirusX
Prole
Posts: 5
Joined: Sat May 17, 2014 11:58 am

Re: Problem with atan2

Post by VirusX »

HugoBDesigner wrote: It may not work 100%, but where I used it it worked fine. I hope I helped!
In your code you use math.offset which is afaik not Lua builtin function? Can you let me know what it does.

Roland_Yonaba wrote:JUst wanted to point out something.
Love system coordinates is not the same as the one assumed in a classical euclidian space.
In LÖVE, x is positive and grows when moving right, and y is positive and grows when moving down. The center is the left-upper bottom of the screen. This is not odd, most of game frameworks uses the same convention.
But, in a euclidian space, the classical one taught at school, we often assume x is positive and grows when moving right, and y is positive and grows when moving up (as opposed to LÖVE's system of coordinates).
Therefore, I think flipping the dy sign in your function fixes everything.
Sorry, I forgot to mention that I suck at maths, but I'm trying by best so don't beat me with the stick yet (: Anyway, I tried your example and it's still working arseways:
Screen Shot 2014-06-02 at 18.10.16.png
Screen Shot 2014-06-02 at 18.10.16.png (34.61 KiB) Viewed 4291 times
It is "looking" to that direction but not where I expect... it should be about 60deg (where second white line is), but I'm getting ~26deg
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Problem with atan2

Post by Roland_Yonaba »

My bad. Just use the return value of math.atan2(dy, dx) straight as the rotation argument to love.graphics.draw.
VirusX
Prole
Posts: 5
Joined: Sat May 17, 2014 11:58 am

Re: Problem with atan2

Post by VirusX »

Roland_Yonaba wrote:My bad. Just use the return value of math.atan2(dy, dx) straight as the rotation argument to love.graphics.draw.

Code: Select all

function lookAt2(obj, target)
  local dx = target.x - obj.x
  local dy = -(target.y - obj.y) -- same as obj.y - target.y
  return math.atan2(dy, dx)
  --return rad < 0 and rad + math.pi*2 or rad
end
It still gives me same result. rad: ~0.46 (deg: ~26.5). Not sure what I'm doing wrong :/
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Problem with atan2

Post by HugoBDesigner »

VirusX wrote:
HugoBDesigner wrote: It may not work 100%, but where I used it it worked fine. I hope I helped!
In your code you use math.offset which is afaik not Lua builtin function? Can you let me know what it does.
Oh, sorry, I just copy-pasted it, so I haven't really checked it. It's a function that pushes a value into a limit. If it's n more than the maximum value, it'll return the minimum value plus n. Kind of what math.mod does, except that you can have custom values. I just made that to be easier. Here it is:

Code: Select all

function math.offset(n, mn, mx, f)
	local n = n
	local f = f or mx
	if math.abs(mn-mx) > f then f = mx end
	while n >= mx do
		n = n - f
	end
	while n < mn do
		n = n + f
	end
	return n
end
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Problem with atan2

Post by Roland_Yonaba »

VirusX wrote:
Roland_Yonaba wrote:My bad. Just use the return value of math.atan2(dy, dx) straight as the rotation argument to love.graphics.draw.

Code: Select all

function lookAt2(obj, target)
  local dx = target.x - obj.x
  local dy = -(target.y - obj.y) -- same as obj.y - target.y
  return math.atan2(dy, dx)
  --return rad < 0 and rad + math.pi*2 or rad
end
It still gives me same result. rad: ~0.46 (deg: ~26.5). Not sure what I'm doing wrong :/
Hi,
Well, I guess I am getting rusty. There is been a long time I have played with LÖVE, and I forgot another minor detail. Added to the fact that y coordinates are flipped upside down, rotation is clockwise, and I was assuming it was anti-clockwise.
This should hopefully work. :awesome:

Code: Select all

function lookAt(obj, target)
  local dx = target.x - obj.x
  local dy = target.y - obj.y
  local a = math.atan2(-dy, dx)
  return math.pi/2 - a
end
VirusX
Prole
Posts: 5
Joined: Sat May 17, 2014 11:58 am

Re: Problem with atan2

Post by VirusX »

Roland_Yonaba wrote: Hi,
Well, I guess I am getting rusty. There is been a long time I have played with LÖVE, and I forgot another minor detail. Added to the fact that y coordinates are flipped upside down, rotation is clockwise, and I was assuming it was anti-clockwise.
This should hopefully work. :awesome:

Code: Select all

function lookAt(obj, target)
  local dx = target.x - obj.x
  local dy = target.y - obj.y
  local a = math.atan2(-dy, dx)
  return math.pi/2 - a
end
You are a star mate!! Thank you so much that works bang on.
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests