ncollide icon indicating copy to clipboard operation
ncollide copied to clipboard

Fixed point type for world coordinates

Open kkimdev opened this issue 10 years ago • 4 comments

I think logically it makes more sense to use fixed-point to represent absolute coordinates.

Reasons to avoid floating-point:

  • Precision depends on position. e.g., (0, 0, 1000000).
  • People should avoid positions too far from the origin.

Fixed-point:

  • Pro: guarantees position-invariant precision. Arguably bits are used more efficiently.
  • Con: Hard max&min values, and have to take care of proper scaling.

But I would argue that anyways people should avoid positions too far from the origin, so the hard max&min values are not really bad, maybe even good because it makes the limitation more explicit.

Since ncollide abstracts the underlying number types. I think what we need here is a clear type distinction of absolute coordinate type and distance type. If user wants to use f32 for the both, it should be OK too.

related article: http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[A%20matter%20of%20precision]]

kkimdev avatar Apr 28 '15 11:04 kkimdev

Operations in pseudo code:

result_position = position + (distance as fixed)
result_position = position - (distance as fixed)

result_distance = (position1 - position2) as float
result_distance = distance1 + distance2
result_distance = distance1 - distance2

position1 + position2 // operation not supported

kkimdev avatar May 01 '15 01:05 kkimdev

So if I understand correctly, the main idea is to use fixed points for absolute coordinates (because they might become very large), and to use floating points for deltas (because they will usually be pretty close to zero). While I agree this makes some sense (and this could be worth a try), I'm concerned about how much complexity this adds to the implementation.

This distinction at the type level between positions and displacements already exists in ncollide : things that implements the Point trait are absolute positions, and those implementing the Vector trait are relative ones. Concretely, this translates to using the Pnt1, Pnt2, Pnt3 (resp. Vec1, Vec2, Vec3) point (resp. vector) types from nalgebra. Your one-dimensional example given above can be done using one-dimensional points and vectors. Subtraction of points output vectors, and addition of points are already forbidden.

Currently points and vectors are assumed to use the same scalar types but I guess that could be modified to allow different ones without to many difficulties (as soon as associated types start to actually work). Then there is the Isometry trait that is more problematic. This trait represents rotation+translations and no distinction is made between translations that are actually absolute positions, and those that are relative ones. I have the feeling that making this distinction would not be practical at all since most algorithm don't care about the actual meaning of those isometries.

All in all, I think supporting the fixed-point/floating point cooperation is possible with minor modifications of the Point and Vector traits and a more detailed work on the Isometry trait found on the ncollide_math subproject. This would also amount to defining new types to represent the couple rotation+position that use distinct scalar types for rotations (e.g. floats) and for positions (e.g. fixed point). I am in favor of trying this, but if in the end this does not prove to be actually useful (as of today, even extremely realistic physics engines use floats only and work just find, sooo...), I would remove it in order to simplify the API.

Unfortunately any progress on ncollide is blocked by #72 , so I can't say when we could attempt to implement this.

One last detail : I don't think there exists a crate that implements fixed-points arithmetic in Rust yet !

sebcrozet avatar May 01 '15 21:05 sebcrozet

Yeah, as you said, I'm also not sure whether it will be worth or not, although I think logically it makes sense to do. I've talked to few people, and a common response is "why not just use double if it becomes really a problem". Someone told me that there is a game that translates the world coordinate center if it moved too far but I forgot the title. I haven't thought about Isometry, good point.

kkimdev avatar May 01 '15 23:05 kkimdev

I'd say Julia's https://github.com/JuliaGeometry/GeometricalPredicates.jl is quite relevant here. All floats are 64 bit between 1.0 and 2.0 so that the decimal portion of point coordinates has a one-to-one mapping with (arbitrary-precision) integers.

0joshuaolson1 avatar Oct 05 '15 04:10 0joshuaolson1