3D - Precision loss

etienne_marais

Honorary Master
Joined
Mar 16, 2008
Messages
16,250
Reaction score
19,740
Location
Centurion
There is a term for it, read it recently but forgot what it is.

Basically I have written a small gfx program that rotates a cube around the z-axis.

private Point RotZ(double degree, Point p)
{
Point r = new Point(p.X, p.Y);
r.X = (int)(p.X*Math.Cos(degree) - p.Y*Math.Sin(degree));
r.Y = (int)(p.X*Math.Sin(degree) + p.Y*Math.Cos(degree));
return r;
}

In the main loop: p1 = RotZ(Math.PI / 20, p1); // (and same for other points)

After many iterations of the loop, p1 loses accuracy/precision/whatever so the effect is that the cube becomes smaller and smaller with more iterations of the loop as the 8 points lose 'accuracy'.

I suppose one way to prevent this is to keep track of the angle you are rotating and have that increase instead of reassigning the points each iteration (so the points' values stay the same and you simply rotate a set of new points relative to the original).

I would like to know however how this is typically handled in real applications.
 
Last edited:
I can also recover the original points after a full rotation (or even 90 degrees) as it is at the moment, but then you are assuming you will reach an initial state after a series of transformations which is not what I want.
 
What are the variable types inside of your Point object? Is everything a double or do you have an integer somewhere? You could be inadvertantly flooring a double to an integer somewhere.
 
1. Your object is shrinking because you're doing (int), which is throwing away fractions. E.g. 3.4 -> 3. So your object will be snapping to int x and y and grow smaller
2. As you suggest, you can store base values + updated rotation angles, you don't overwrite the original vertices. Even if using ints (which is imprecise) then it'll work
3. Leave it as is and change all your ints to float for all calculations (can use double but that's a lot slower than float). Then it'll run a lot longer
4. More advanced, look into _controlfp(_PC_24, _MCW_PC) and _controlfp(_RC_NEAR, _MCW_RC) to alter the precision of floating point ops
 
Thanks guys, years ago I did something similar but I used double all the way (except of course for putpixel which required int params), but over a very large amount of iterations the data loss creeped in as well but I will try to rewrite first and then try point 4. from the previous post. I would like to do it right as I am delving into more advanced 3D, i.e. an elementary 3D engine for a start.
 
Computers don't work with numbers the way that humans work with maths; Most values are approximations (though to a very small degree). Doubles store 52 bits after the decimal point (0~52 = fraction, 53~63 = whole, 64 = sign +/-), so if a resultant of something like an irrational number requires 53 bits after the decimal, it will just end up rounding it up or down, thus resulting in a loss in precision. This may be the problem.

Have a look here: http://www.codeproject.com/Articles/25294/Avoiding-Overflow-Underflow-and-Loss-of-Precision
 
Last edited:
Top
Sign up to the MyBroadband newsletter
X