Lua rounding and comparation of floats

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
feodosian
Prole
Posts: 4
Joined: Mon Jun 18, 2012 8:29 am

Lua rounding and comparation of floats

Post by feodosian »

Hi

i have question about lua and game development.
Problem that lua round's values and when i compare this rounded values they a minimally lower or greater than they should be.

E.g.

I have to 2 vectors and i want find point of their crossing (if such exists). I find point of crossing between 2 lines on which every vector lie and than check this points x,y that it in range of every of 2 vector boundaries.

vector1 = { { x=548, y=503 }, { x=381, y=133 } }
vector2 = { {x = 700, y= 500}, {x = 10, y = 500} }

crossing point - x = 546.64594594595 , y = 499.9999999999 and this point doesn't lie on vector2. I attach lua file with this example.

My question is - how did you solve such precision problems in base. I understand that concrete in this example i can round this values, but maybe it exists some base rule to solve such problems or it needed simply round all numbers before comparation?

P.S.
I am newbie
Attachments
test3.lua
(2.15 KiB) Downloaded 180 times
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Lua rounding and comparation of floats

Post by kikito »

Assuming there is no error in your calculations, if the point is "out" of vector2, even for a tiny fraction, then I would consider that there is simply no collision. I would act as if the vectors were 2 million units away. No messing around with rounding numbers of any kind.

If you need the collision to happen for some reason, the obvious option is moving the vectors. Not when doing the calculations, but from the start. Move v1 or v2 1 pixel in any direction so that the collision "really happens".
When I write def I mean function.
User avatar
feodosian
Prole
Posts: 4
Joined: Mon Jun 18, 2012 8:29 am

Re: Lua rounding and comparation of floats

Post by feodosian »

kikito wrote:Assuming there is no error in your calculations, if the point is "out" of vector2, even for a tiny fraction, then I would consider that there is simply no collision. I would act as if the vectors were 2 million units away. No messing around with rounding numbers of any kind.

If you need the collision to happen for some reason, the obvious option is moving the vectors. Not when doing the calculations, but from the start. Move v1 or v2 1 pixel in any direction so that the collision "really happens".
Thx for answer, i understand your point - you mean that i should not worry about very near collision (my perfectionism). But i mean not this problem. In my example 2 vectors are crossing

Image

But because of internal rounding of floats point of crossing calculated minimally not where it is in real, like marked at picture.

Okay , another example of internal rounder. This code:

Code: Select all

t1 = 499.9999999999999999999999999999999999999999999999
t2 = 499.99

print(t1 == 500, t2 == 500);
Result of running this code:

Image

Same happens with vector crossing calculation.
User avatar
vrld
Party member
Posts: 917
Joined: Sun Apr 04, 2010 9:14 pm
Location: Germany
Contact:

Re: Lua rounding and comparation of floats

Post by vrld »

This is not a Lua-specific phenomenon, but has to do with how computers represent (real) numbers in general. The basic issue is that your processor has only a finite amount of space to express an infinite amount numbers. If you are interested to learn more, you should visit this site or read this thorough (but complicated) paper.

Regarding your issue: You can use soft conditions. Instead of testing whether two numbers are equal, you test whether the difference is 'small enough'. In your particular example you can use the scalar product test if a point is very close to a line or not:

Code: Select all

-- x,y: Point to test
-- x1,y1, x2,y2: points that define the line
-- eps: Allowed deviation
function pointOnLine(x,y, x1,y1, x2,y2, eps)
    eps = eps or 1e-10
    local dot = (x-x1)*(x2-x1) + (y-y1)*(y2-y1)
    -- dot product is close to 0 if two vectors are almost parallel
    return dot < eps
end
You might have to twiddle this function a bit and maybe add a check if the point lies in between (x1,y1) and (x2,y2), but I hope you get the general idea.
I have come here to chew bubblegum and kick ass... and I'm all out of bubblegum.

hump | HC | SUIT | moonshine
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Lua rounding and comparation of floats

Post by Inny »

For a moment, consider the difference between the concepts of mathematics, and the principles of gaming. In mathematics, a line is an infinitely thin and infinitely long collection of points which are exactly defined. In gaming, a line is a long and thin segment you jump over, or bounce off of, or otherwise interact with. Since LoVE is a backend host for games, and not a graphing calculator, the question becomes what gaming principles should we apply, rather than how strict can we simulate math.

So, is the point (5.999999999999, 3.000000000001) on a line segment defined by points (1, 3) and (9, 3)? Sure. If this game were a platformer, it'd be close enough to be considered on the floor, and to allow the player to make a jump.

An interesting follow up is this blog post by Adam Atomic on how he tuned Canabalt to make it more playable: http://blog.semisecretsoftware.com/tuning-canabalt
User avatar
feodosian
Prole
Posts: 4
Joined: Mon Jun 18, 2012 8:29 am

Re: Lua rounding and comparation of floats

Post by feodosian »

Thx , to vrld and Inny for useful info. But it should be interesting (i hope not only for me), how you solve such problems?
Now i have one general solution round ( http://en.wikipedia.org/wiki/Rounding#R ... _from_zero ) all numbers before comparation.
mlepage
Prole
Posts: 10
Joined: Sat Jun 30, 2012 9:26 pm

Re: Lua rounding and comparation of floats

Post by mlepage »

Generally, you would use thresholds in your comparisons, to tell if it is "close enough".

It's not that the floating-point operations are inaccurate, since they are perfectly accurate and deterministic (repeatable). It's that they aren't real math, they are a model (approximation). They represent something very close to numbers and math, but not exactly the same.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest