Sign in to follow this  
Sean_Seanston

Should positions be defined as ints or floats?

Recommended Posts

Up to now, I've just decided to use floats to store the positions of objects in my basic 2D games figuring I may as well and it might help keep things smooth at some point or if I ever need to add a gradation of less than 1 to a position then at least I'll be able to without changing things from int to float.

Now I've come into a problem that makes me wonder again whether ints or floats are a better idea.

I'm trying to implement a collision handling algorithm that takes 2 colliding objects' old positions and their velocities, then moves them back toward their old positions gradually until no collision occurs.
Only after writing the code and running it a few times, outputting some debugging info, did I realize that the floats I was using for position were complicating things. I was trying to decrement (or increment) the velocities but since they and the positions were floats, subtracting/adding 1 didn't seem to make as much sense as it would've with ints and my code to get the decrementing/incrementing to stop at 0 wasn't working because it skipped over being exactly 0 if the values weren't equal to exact integers.

I could clean that up of course and get around it, but I'm back wondering something I've been wondering about for some time but was never forced to think about very much: Should object positions (specifically in 2D games moreso) be floats or are integers generally just as good and easier/more logical to work with? What are your experiences with this? Should I go back and change the floats to ints or are there significant advantages to using floats?

Share this post


Link to post
Share on other sites
Floats aren't 100% precise but this is a problem based on calculations being base 2 and can cause some collision errors.

Int would be simplest to work with, it's easy to iterate and most positions in games can be scaled up or down to an int. Unless you're doing calculations that require you to use fractions or division (really the same thing)...I don't suggest using float.

Share this post


Link to post
Share on other sites
For a 2D game I would recommend either using fixed-point (e.g. 24.8 format), or just sticking with floating point.

Using integer positioning results in very jagged movement. Once you've properly used Fixed-point, you wont be able to stand how jumpy using straight out integer coordinates is.

Share this post


Link to post
Share on other sites
[quote name='ApochPiQ' timestamp='1311032171' post='4837098']
Sounds like floats aren't the problem so much as your methods for comparing them.[/quote]

How are floats for position in 2D games in general though?

I suppose I'll stick with them either way at this stage...

[quote name='ApochPiQ' timestamp='1311032171' post='4837098']Since floating point numbers are inherently imprecise, you need to use an [i]epsilon value[/i] to check if they are (almost) equal. So for instance:

[code]// Bad
if(some_number == 2.0f) { foo(); }

// Good
if(abs(some_number - 2.0f) < 0.0001f) { foo(); }[/code][/quote]

Hmmm... good idea. I'll keep that in mind.

[quote name='kburkhart84' timestamp='1311051513' post='4837208']
If it is 2d, and pixel based, you may as well go with integers. Of course, if it were 3d, you would likely be stuck with floats, unless it were grid-based.[/quote]

Well being that I've gone with floats so far... I guess I'll keep them. Might be good practice for future 3D stuff too to an extent.

[quote name='iMalc' timestamp='1311058279' post='4837234']
Using integer positioning results in very jagged movement. Once you've properly used Fixed-point, you wont be able to stand how jumpy using straight out integer coordinates is.[/quote]

Yeah... I thought about jaggyness but my current system uses interpolation to smooth out movement, so objects are drawn at float coordinates in between their last 2 positions or thereabouts so it looks nice and smooth. Not sure then what way I have it exactly if switching to ints would cause a problem... but I'll just stick with them now.

Question:
- When I'm slowly stepping the objects back to check for the first point where they don't intersect, what increment should I use? Is 1.0 too large? Another thing is that maybe no matter what step I use, I'll end up where the objects aren't exactly rubbing against each other like would be ideal, since we're not checking every single possible position like would be easy with integers.

So how should I really approach this kind of algorithm with floating points anyway? Accept the small gaps between objects that are bound to occur (realistically probably wouldn't make a noticeable difference I assume)? Or is there some better way?
Part of why I thought stepping would be better was that I wouldn't have to deal with if statements determining what side things were approaching from in order to determine whether they should be set to hug the edge of the other object, but with floats it seems doing it exactly would be complicated but I dunno.

Thoughts?

EDIT: Does anyone have any links to anywhere discussing this kind of algorithm? I've started to encounter a lot of complications I can't figure out how to solve... such as how to stop velocity being reduced when it shouldn't be like when object 1 is going straight up, but object 2 runs into the side of it, object 1's y velocity shouldn't be touched..

Share this post


Link to post
Share on other sites
Okay, here's what I mean... I've drawn a diagram that I hope is easy to follow, illustrating 2 different cases of movement and a resulting collision, where the objects' positions + velocity result in the same positions in each case but where different behaviour would be expected:
[img]http://img638.imageshack.us/img638/5102/collisiondiagram.png[/img]

In the diagram, the green shapes represent objects in their initial positions, red shapes represent their initial positions + velocities, and red arrows represent direction of movement to make it slightly clearer.
In Case 1, Object 1 slams into the side of Object 2 as it travels upwards. The desired effect would be for Object 2 to be unaffected and Object 1 to be repositioned as close to Object 2 as possible along the X axis without overlapping with it.
Case 2 results in the same end positions if the velocities were to be added to their previous positions, but this time, Object 2 is coming up from beneath Object 1 and colliding. Here you'd want Object 1 to be unaffected and Object 2 to be repositioned next to Object 1.

How might you factor all of this into such an algorithm? Clearly, the initial positions must be taken into account but I don't trust myself to come up with something that works without a maze of if statements or switches and elaborate boolean statements.Then of course it has to work on all other cases such as diagonal movement and with only 1 and both moving etc. etc.

Share this post


Link to post
Share on other sites
Well it seems everyone explained pretty in depth the particularities of floating point regarding logic, but I see no mention to render, so I'll get on that particular topic.

Yes, traditionally position is declared and stored as floating point, and yes performing an equality check on a float is virtually pointless.
Having said that, in a 2D world, you should also have a uniform method to turn float positions into int for rendering purposes, see, textures are rendered by discrete portions we call pixels, since they are discrete, they cannot have a meaningful decimal position. The graphics card will try to round up your floats into ints, however this often generates graphic artifacts in 2D, specially for tile maps, rounded positions may not preserve relative distances and therefore leave gaps between tiles or overlap tiles, specially when scrolling the camera with a floating point controlled position.


Making the conversion yourself can prevent this well enough

Share this post


Link to post
Share on other sites
Hmmm... I see what you mean NEXUSKill... makes sense... I'll have to keep that in mind. Don't THINK it's been causing me problems yet though. I'll have to keep an eye out in future.

Anyone have any ideas re: my diagram problem?

I've heard of this collision handling method before so there must be some fairly standard ways of doing it.

Share this post


Link to post
Share on other sites
[quote][color="#1C2837"][size="2"] The graphics card will try to round up your floats into ints, however this often generates graphic artifacts in 2D[/quote][/size][/color]
[color="#1C2837"] [/color][color="#1C2837"][size="2"]This is hardly true at all. All operations done on the a graphics card are floating point from fragment transformation to rasterization. Floating point values are valuable to the graphics card. Anti-aliasing requires sub-pixel measurements. When it comes time to writing the color to video memory a simple integer truncation is performed, no rounding. And to get technical, you can have a discrete set of decimals. Think of a set containing values in increments of 0.5..[/size][/color]

Share this post


Link to post
Share on other sites
[quote name='Sean_Seanston' timestamp='1311166474' post='4837943']
Okay, here's what I mean... I've drawn a diagram that I hope is easy to follow, illustrating 2 different cases of movement and a resulting collision, where the objects' positions + velocity result in the same positions in each case but where different behaviour would be expected:
[img]http://img638.imageshack.us/img638/5102/collisiondiagram.png[/img]

In the diagram, the green shapes represent objects in their initial positions, red shapes represent their initial positions + velocities, and red arrows represent direction of movement to make it slightly clearer.
In Case 1, Object 1 slams into the side of Object 2 as it travels upwards. The desired effect would be for Object 2 to be unaffected and Object 1 to be repositioned as close to Object 2 as possible along the X axis without overlapping with it.
Case 2 results in the same end positions if the velocities were to be added to their previous positions, but this time, Object 2 is coming up from beneath Object 1 and colliding. Here you'd want Object 1 to be unaffected and Object 2 to be repositioned next to Object 1.

How might you factor all of this into such an algorithm? Clearly, the initial positions must be taken into account but I don't trust myself to come up with something that works without a maze of if statements or switches and elaborate boolean statements.Then of course it has to work on all other cases such as diagonal movement and with only 1 and both moving etc. etc.
[/quote]

In all honesty i would stick to floats for position and stop trying to do this yourself, go look at box2d and more than likely it solves all your issues without me getting into all the reasons even the correct answer to this can fail in "other" cases. I stopped trying to do my own physics (in cases where I cared about the complicated potential interactions) when Pentium 2 was new and shiny. It's just not worth the effort if you can use a very well tested library for free.

Share this post


Link to post
Share on other sites
Sorry to pull this a little off topic... but...

I hate the phrase "It's just not worth the effort if you can use a very well tested library for free."

It is worth every effort to try and build it yourself, the reward from figuring out this kind of problem is fantastic when you can sit back and say, "geez, i've just worked out (sure with a little help) how to do something that some of the best programmers in the world have issues with".

Share this post


Link to post
Share on other sites
If you don't have much experience, you should definitely go with floating point, and preferably use an existing library. Box2d is pretty good.


I'm currently working on a fixed point physics engine, and it definitely isn't easy. The main thing is that it forces you to think very carefully about all your algorithms. Fixed point has some advantages, such as better portability, robustness, determinism, and more control over precise errors, but it also takes a lot more work to implement. Note: performance is not an advantage, at least if you're targeting modern CPUs.

Share this post


Link to post
Share on other sites
[quote name='Seriphis' timestamp='1311212329' post='4838232']
Sorry to pull this a little off topic... but...

I hate the phrase "It's just not worth the effort if you can use a very well tested library for free."

It is worth every effort to try and build it yourself, the reward from figuring out this kind of problem is fantastic when you can sit back and say, "geez, i've just worked out (sure with a little help) how to do something that some of the best programmers in the world have issues with".
[/quote]


That really depends on your goals.

If your goal is to do something hard, then sure, masochistic wheel-reinvention is great; if your goal is to make a cool game, why bother?

Share this post


Link to post
Share on other sites
Well in some cases, the gameplay you want can't be supported by an existing physics engine. And obviously there are other possible reasons too. But I suppose that was a rhetorical question.

Share this post


Link to post
Share on other sites
[quote]the gameplay you want can't be supported by an existing physics engine[/quote]

and in some cases can be as hard to understand and use effectively as writing it yourself.

In short, if you use a tool to do something you dont understand yourself how can you prove its working?
Monkey's can use calculators and they will work as intended, but garbage in = garbage out.

Share this post


Link to post
Share on other sites
[quote name='Seriphis' timestamp='1311227813' post='4838321']
In short, if you use a tool to do something you dont understand yourself how can you prove its working?
Monkey's can use calculators and they will work as intended, but garbage in = garbage out.
[/quote]
I can't really think of an example of using a library where you would not be able to asses whether the results are expected or not. After all, you wouldn't be using the library in the first place unless you were using it to solve a specific problem. More to the point, by using library code, you know it's been road tested. Rolling your own? Well, you'll be spending a LOT of time testing to see if the results are as expected, time that would be better spent actually developing your game. If you want to roll your own for academic purposes, sure, why not. But for production, I really cannot the justification for investing so much time re-inventing the wheel.

Share this post


Link to post
Share on other sites
[quote name='Seriphis' timestamp='1311212329' post='4838232']
Sorry to pull this a little off topic... but...

I hate the phrase "It's just not worth the effort if you can use a very well tested library for free."

It is worth every effort to try and build it yourself, the reward from figuring out this kind of problem is fantastic when you can sit back and say, "geez, i've just worked out (sure with a little help) how to do something that some of the best programmers in the world have issues with".
[/quote]

I don't dissagree with the sentiment but if the intention is to complete a game, getting stuck on a complex problem such as this is the wrong thing to do. If this is purely learning and or experimental, sure, write it yourself and learn the wonders of multi-contact/penetration issues which make even the 2D case a nightmare of complexity. As such, been there, done that, don't suggest it unless you really want a headache. :)

Share this post


Link to post
Share on other sites
[quote name='zerothrillz' timestamp='1311206817' post='4838199']
[color="#1C2837"][size="2"]This is hardly true at all. All operations done on the a graphics card are floating point from fragment transformation to rasterization. Floating point values are valuable to the graphics card. Anti-aliasing requires sub-pixel measurements. When it comes time to writing the color to video memory a simple integer truncation is performed, no rounding. And to get technical, you can have a discrete set of decimals. Think of a set containing values in increments of 0.5..
[/size][/color][/quote]


2D tilemap based games rarely use anti-aliasing, specially those that use the sharp edges of pixels as an aesthetic resource instead of trying to compensate it, and the graphic error I mentioned is a very common one that I've seen in many games that assumed the graphics card would do all the magic for them, I've even seen the same error in 3D games that used tiled terrain meshes that displayed seams due to rounding errors

Share this post


Link to post
Share on other sites
I suppose really, I'd like to both complete my current game and learn something from implementing this kind of algorithm if at all possible. Shortcuts are nice, but like Seriphis said, it's nice to have the satisfaction of doing things like this yourself, especially when it's such a core concept in game development.

I see Box 2D is open source... I might research that a bit and see if I can learn anything. Are there no relatively popular articles/tutorials around about this kind of thing though? I could swear I heard a lot about this kind of thing before I decided to actually try it myself, but then I dunno.

Is making 2 moving 2D objects collide with each other really that difficult? Maybe destroying one of them outright is much more common I suppose... I could look into just doing that for the purposes of my current game but I'd still like to be able to collide things like this.

Share this post


Link to post
Share on other sites
[quote name='Sean_Seanston' timestamp='1311289735' post='4838691']
I suppose really, I'd like to both complete my current game and learn something from implementing this kind of algorithm if at all possible. Shortcuts are nice, but like Seriphis said, it's nice to have the satisfaction of doing things like this yourself, especially when it's such a core concept in game development.

I see Box 2D is open source... I might research that a bit and see if I can learn anything. Are there no relatively popular articles/tutorials around about this kind of thing though? I could swear I heard a lot about this kind of thing before I decided to actually try it myself, but then I dunno.

Is making 2 moving 2D objects collide with each other really that difficult? Maybe destroying one of them outright is much more common I suppose... I could look into just doing that for the purposes of my current game but I'd still like to be able to collide things like this.
[/quote]

I think collision detection has fallen out of favor in the research communities for the most part due to the fact that there are plenty of open source/closed source solutions available and very few companies are willing to fund teams to write in house solutions instead of just using an existing library. Now, given that, if you want some of the older research you might start by looking at CCD (continuous collision detection) which is the primary solution anymore. Going through the Box2d code is probably the most likely learning source as it puts all the various pieces together in context. Or, the book Realtime Collision Detection For Games (think that's the one based on Solid) which does a good job of going through all the problems and how to solve them.

And just to be complete, some more searchable terms which are all generally related to collision detection in various ways:

Penetration calculations (say sphere/sphere, sphere/box etc)
Sweep and Prune
Time of contact calculations (again, various primitives)
All forms of closest point calculation with various primitives.

Lots more but the above can keep you busy for a while.

Share this post


Link to post
Share on other sites
[quote name='NEXUSKill' timestamp='1311262896' post='4838483']


I've even seen the same error in 3D games that used tiled terrain meshes that displayed seams due to rounding errors

[/quote]


yes it is a question of rounding error, but it happens most likely because of a T-junction in the terrain mesh. If the adjacent tiles have exactly the same edge positions, there shouldn't be any seams visible.

Best regards!


Share this post


Link to post
Share on other sites
[quote name='AllEightUp' timestamp='1311339654' post='4838879']
Lots more but the above can keep you busy for a while.[/quote]

Cool, looks like it should. I'll see what I can figure out and move forward based on whatever I find...

Thanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this