0

I'm developing map-based game using cocos2d v3.

I have a map with size of 2^19 points. On that map I have object that should move over time in short distance. About 60-70 points.

    CGPoint offset = [_trajectoryPath offsetForNextPosition];

    CGFloat x = self.position.x + offset.x;
    CGFloat y = self.position.y + offset.y;

    self.position = CGPointMake(x, y);

At such map size map position can be something like {300000, 40000} points. When I try to add small step, lets say about {0.002f, 0.004f}, to animate object position I end up with still the same {300000, 40000} points...

I understand that it happens because of precision of float. Values normalised by map size, to be between 0 and 1.0, don't work either.

Is it possible somehow to increase precision of float type on iOS? Or may be someone cam give a hint about possible workaround for this problem?

Thanks.

James Webster
  • 31,873
  • 11
  • 70
  • 114
  • 4
    CGFloat has double precision already, but it is not a precision error... you must have another error somewhere. How is self.position declared? – Volker Mar 18 '14 at 14:08
  • 5
    `CGFloat` is only double precision on 64-bit platforms. Any iOS device older than the iPhone 5S only runs 32-bit apps, where `CGFloat` is still single precision (24 bits of significand). – rob mayoff Mar 18 '14 at 14:32
  • 1
    I would question your intent first before considering to answer the question. A map where objects can be at point coords in the hundred thousands, if not millions, is absolutely extreme. I hope you were doing a number of reality checks like writing down the byte sizes of data structures, how many of them you'll have on your map, and whether that'll reasonably fit in memory. Say your map stores on average 1 Byte per square point you'd have a memory consumption of 80+ Gigabytes (!) on a map sized 300,000 x 300,000. – CodeSmile Mar 18 '14 at 16:13
  • Just FYI Minecraft is a gigantic world, and it is known that they have a floating point inaccuracy issue on the far fringes of the world. But so far, no one has ever gotten there despite one player who set out to travel in one direction continuously. – CodeSmile Mar 18 '14 at 16:18
  • 1
    Maybe the floating point inaccuracy are the reason why he never arrived... – gnasher729 Mar 18 '14 at 16:23
  • @LearnCocos2D, if you check the implementation of a MKMapView, you'll find, that underlying `UIScrollView` have almost the same `contentSize`, about 2^19. Since the map is tiled and single tile is somewhat of 256 x 256 pixels, and there's no need to keep all the tiles in memory, you are far from reaching 80 Gigabytes of occupied RAM. However, objects on map, like pins, can be placed in any location, and their coordinates are between 0 and 2^19 - 1 on zoom level that is closest to Earth surface. – anticyclope Mar 19 '14 at 04:14
  • @LearnCocos2D We have implemented a simple map engine using Mapbox as a source for tiles, and we keep an eye on the client's RAM not to be blown up by this images :) You can think of the map as an empty vast space where we need to animate smth smoothly in very short distances. – mightee.cactus Mar 19 '14 at 07:59
  • Similar issue discussed [_here_](http://stackoverflow.com/questions/12857992/when-cgpointmake-meets-big-number), but there is just a question – mightee.cactus Mar 19 '14 at 08:36
  • Good to hear that from time to time I'm wrong with my assumptions and a developer actually put his head to work instead of setting out to work straight away on what will be an impossible project. :) – CodeSmile Mar 19 '14 at 09:46
  • @LearnCocos2D Irony accepted :) It seems we'll have to chop the map to the smallest possible size and get/handle all issues along with such solution... Unfortunately I was too optimistic about float :) – mightee.cactus Mar 20 '14 at 06:52
  • Just an idea. You can also represent coordinates with NSInteger or even uint64_t. That is if you don't need sub-pixel precision. Even so you can use the old-school game dev trick of using two integers to represent a floating point value. There's probably examples out there, the math isn't too involved and can be hidden within a helper class. – CodeSmile Mar 20 '14 at 10:41
  • @LearnCocos2D thanks for the tip, I'll check it out. – mightee.cactus Mar 21 '14 at 09:43

1 Answers1

0

mightee.cactus, I remember we had a similar issue while adding very small numbers to very large ones with float in c.

The solution was follows: we changed types to double to preserve accuracy; in your case you can make all the arithmetic operations with doubles and translate them into CGFloat just before use in CGPointMake.

romaroma
  • 658
  • 8
  • 13
  • I can cast values to double at the time of calculation, but after all I must assign it back to the type of float, that just can't hold such big values. – mightee.cactus Mar 19 '14 at 07:52