Predictable sin/cos rounding errors?

Started by
11 comments, last by HopeDagger 15 years, 9 months ago
This really smells like a rookie mistake to me, so I felt this belonged best in the beginners' forum. The relevant code in question is as follows:

		const float rot = 45;
		float cos_v = cos(rot*D2R);
		float sin_v = sin(rot*D2R);

		for(int x=-6; x <= 6; x += 1)
		{
			for(int y=-6; y <= 6; y += 1)
			{
				float fx = x*32;
				float fy = y*32;
				int dx = (int)(cos_v * fx - sin_v * fy);
				int dy = (int)(cos_v * fy + sin_v * fx);
				pgm->render(SCR_WIDTH/2+dx, SCR_HEIGHT/2+dy);
			}
		}


Where D2R is (pi / 180) and pgm->render(x,y) draws a centred image at the given coordinates. This is a general case with the rotation fixed, but I'm sure the idea is clear. Much to my dismay, this results in a series of small off-by-one errors in rendering: I'm guessing that these are rounding errors, as a result of the multiplications with my precomputed sin/cos values. Or is there something else of a clear-as-day fashion that's just completely missed me? [grin] Many thanks in advance for any assistance. [Edited by - HopeDagger on July 19, 2008 6:50:27 PM]
Advertisement
If anyone needs any clarifications or additional information about the code or the problem, don't hesitate to ask.
Why not try rendering it without precomputed values and see if there are the same artifacts? Actually, try using floats for the positions. Casting each tile's position to an int isn't going to help your accuracy at all. Try using floats for each tile's location and don't cast to an int. I'm going to bet that that is where the problem lies.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Quote:Original post by MikeTacular
Why not try rendering it without precomputed values and see if there are the same artifacts? Actually, try using floats for the positions. Casting each tile's position to an int isn't going to help your accuracy at all. Try using floats for each tile's location and don't cast to an int. I'm going to bet that that is where the problem lies.


Thanks for the response, Mike.

The artifacts appear irregardless of rotation -- I just felt that the 45-degrees case would be the simplest to diagnose.

I'm sure I see what you mean in your other suggestion. In the end, the computer can only render to integer coordinates, so this casting to integers need to happen. Even if I make dx/dy floats and delay that integer casting until the end (inside the parameters), the artifacts remain.

Any other suggestions?
Quote:Original post by HopeDagger
I'm sure I see what you mean in your other suggestion. In the end, the computer can only render to integer coordinates, so this casting to integers need to happen. Even if I make dx/dy floats and delay that integer casting until the end (inside the parameters), the artifacts remain.
What graphics package are you using? Most use floats (and the graphics hardware certainly does - it typically doesn't have any support for integers).

Regardless, I am pretty sure that the round-to-int there is the source of your error.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

I don't mean delay the casting to an int. I mean never cast to an int. For example, if you're using OpenGL to render (I honestly have no idea what you're using), you would do glVertex2f() instead of glVertex2i().
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
@swiftcoder & Mike: I'm using SDL for the rendering portion, which uses integer coordinates in rendering. I've tried both regular cast-to-int rounding, as well as substituted in a proper rounding function, and neither account for the error in drawing.
What happens if rot is zero? Try rotating it real-time. Do you have a problem for ANY angle?

Try a static_cast. I don't know it would help, but it's worth a try, no?
Quote:Original post by Splinter of ChaosWhat happens if rot is zero? Try rotating it real-time. Do you have a problem for ANY angle?


Sorry, I must have not been clear in my original post: these off-by-one errors occur at every angle. I just chose the 45-degrees case as the sample case to show, since it exhibited the errors most clearly.

Quote:Try a static_cast. I don't know it would help, but it's worth a try, no?


static_cast is just a a more restrictive flavour of a c-style cast. This doesn't change anything, unfortunately.

Does pgm->render always draw the same image?
Or is the image drawn also rotated?

This topic is closed to new replies.

Advertisement