Author Topic: [SOLVED] math.atan2() problem  (Read 9272 times)

0 Members and 1 Guest are viewing this topic.

Offline Nick

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1166
  • Rating: +161/-3
  • You just got omnom'd
    • View Profile
    • Nick Steen
[SOLVED] math.atan2() problem
« on: December 29, 2012, 05:57:05 am »
SOLVED SOLVED SOLVED SOLVED SOLVED SOLVED, thanks Jim!
Hi

While working on my Uno game, I discovered something very strange.
I wanted to make an animation in which a card moves from one place to another, and therefore I need to determine the angle between the position is is now, and the position it has to travel to. To do this, I use math.atan2( xdifference, ydifference), which return an angle in radians.

When I let the computer software (runs OS 3.2) calculate everything works fine, and the card moves from the position it is to where it has to go, like it should.
Buut when I run exactly the same code, just transfered via usb, on my calc (nspire cx cas, os 3.1.0.392), it doesn't work. The angle it returns is about half the size of the one from the student software, while using exact the same calculations.

Am I not seeing something? Or is there some mess up with radians vs. degrees on software and calc?

Here's the code:
Code: [Select]
function TheGame:timer()
    local xDif = math.abs(self.movingCardPos[1]-self.defPos[1])
    local yDif = math.abs(self.movingCardPos[2]-self.defPos[2])
    local dirX = xDif/(self.movingCardPos[1]-self.defPos[1])
    
    if xDif<5 and yDif<5 then
        timer.stop()
        table.insert(self.pack, self.movingCard)
        self.movingCard = nil
        self.movingCardPos = nil
    else
        local tan = math.atan2( yDif, xDif )
        if dirX>0 then
            self.movingCardPos[1] = self.movingCardPos[1]-4*math.cos(tan)
        else
            self.movingCardPos[1] = self.movingCardPos[1]+4*math.cos(tan)
        end
        self.movingCardPos[2] = self.movingCardPos[2]-4*math.sin(tan)
        platform.window:invalidate()
    end
end

screenie pc:


screenie calc:


The number in the corner is the value returned by math.atan2(), of which you can see it differs

Solved: I had to update the screenSize after init, because that seems to return 0 at the beginning. Thanks Jim!!
« Last Edit: December 29, 2012, 07:53:21 am by Nick »

Offline Adriweb

  • Editor
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1708
  • Rating: +229/-17
    • View Profile
    • TI-Planet.org
Re: [Lua] math.atan2() problem
« Reply #1 on: December 29, 2012, 06:22:34 am »
It sure is weird, but going from the software 3.2 to the OS 3.1, there might be some unexpected results...

does math.atan() give the same on calc ?
Also, calling the nspire's math engine gives the same (just for testing, it's way too slow to use for real while in calculations, I guess) ?
My calculator programs
TI-Planet.org co-admin.
TI-Nspire Lua programming : Tutorials  |  API Documentation

Offline Nick

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1166
  • Rating: +161/-3
  • You just got omnom'd
    • View Profile
    • Nick Steen
Re: [Lua] math.atan2() problem
« Reply #2 on: December 29, 2012, 07:17:21 am »
does math.atan() give the same on calc ?
I changed the math.atan2(yDif, xDif) by math.atan(yDif/xDif) and that gives the same results as atan2 on pc and calc, so again different values.

Also, calling the nspire's math engine gives the same (just for testing, it's way too slow to use for real while in calculations, I guess) ?
if I do tan-1(150/20) I get the same result on calc and pc (1.44) when in radian, same for degrees, but then 82.4, which is correct.
I also changed the settings to both radian and degrees of both the pc and the calc, but that does not seem to influence anything (just to make sure).

I guess i've tried all possible solutions:
Code: [Select]
local tan = math.atan2(yDif, xDif)
local tan = math.atan(yDif/xDif)
local tan = tonumber(math.eval(""..math.atan2(yDif,xDif)))
local tan = tonumber(math.eval(""..math.atan(yDif/xDif)))
it lways keeps returning 1.44 on pc (correct) and 0.68 on calc (wrong).

edit: I'll redo math.Eval, now it just returns a number of course, since the calculation already happens in lua, brb with the correct values
« Last Edit: December 29, 2012, 07:20:57 am by Nick »

Offline Jim Bauwens

  • Lua! Nspire! Linux!
  • Editor
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1881
  • Rating: +206/-7
  • Linux!
    • View Profile
    • nothing...
Re: [Lua] math.atan2() problem
« Reply #3 on: December 29, 2012, 07:22:04 am »
Could you test if the parameters you give to atan2 are the same?
Maybe some other issue causes certain variables to be different. (such as putting calculation code in your paint function).
Also, can you test just a single atan2 statement, no other code? That way we can see if that function really is the issue.

Offline Nick

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1166
  • Rating: +161/-3
  • You just got omnom'd
    • View Profile
    • Nick Steen
Re: [Lua] math.atan2() problem
« Reply #4 on: December 29, 2012, 07:34:47 am »
darn, when I do this:

Code: [Select]
platform.apilevel = '1.0'

x = 160
y = 120

function on.paint(gc)
    gc:setFont("sansserif","b","8")
    gc:drawString(math.floor(math.atan2(y,x)*100)/100,0,0,"top")
    gc:drawString(math.floor(math.atan(y/x)*100)/100,50,0,"top")
    gc:drawString(x,0,10,"top")
    gc:drawString(y,0,20,"top")
end

I get the correct values on both the nspire as the pc, so there must be something different that causes the wrong answers..

and to be complete, here are both the :timer() and :paint(gc)
Code: [Select]
function TheGame:timer()
    local xDif = math.abs(self.movingCardPos[1]-self.defPos[1])
    local yDif = math.abs(self.movingCardPos[2]-self.defPos[2])
    local dirX = xDif/(self.movingCardPos[1]-self.defPos[1])
   
    if xDif<5 and yDif<5 then
        timer.stop()
        table.insert(self.pack, self.movingCard)
        self.movingCard = nil
        self.movingCardPos = nil
    else
        local tan = math.atan2( yDif, xDif )
        --local tan = tonumber(math.eval("arctan("..yDif/xDif..")"),10)
        if dirX>0 then
            self.movingCardPos[1] = self.movingCardPos[1]-4*math.cos(tan)
        else
            self.movingCardPos[1] = self.movingCardPos[1]+4*math.cos(tan)
        end
        self.movingCardPos[2] = self.movingCardPos[2]-4*math.sin(tan)
        --paintPart(self.movingCardPos[1]-5, self.movingCardPos[2]-5, 60, 90)
        paint()
    end
end

function TheGame:paint(gc)
    if self.movingCard ~= nil then
        local xDif = math.abs(self.movingCardPos[1]-self.defPos[1])
        local yDif = math.abs(self.movingCardPos[2]-self.defPos[2])
        local tan = math.atan2( yDif, xDif )
        --local tan = math.atan( yDif/xDif )
        --local tan = tonumber(math.eval("arctan("..yDif/xDif..")"),10)
        gc:setFont("sansserif","b","8")
        gc:drawString(tan,0,0,"top")
        gc:drawString(self.movingCardPos[1],0,10,"top")
        gc:drawString(self.movingCardPos[2],0,20,"top")
    end
    local img = image.new(Cards[1][1])
    for i=1,1 do
        self.players[i]:paint(gc, i)
    end
    self.pack[#self.pack]:paint(gc, (getWidth()-image.width(img))/2, (getHeight()-image.height(img))/3)
    if self.movingCard ~= nil then
        self.movingCard:paint(gc, self.movingCardPos[1], self.movingCardPos[2])
    end
end
« Last Edit: December 29, 2012, 07:40:20 am by Nick »