Date: Wed, 11 Sep 1996 03:36:41 +0800 (GMT) From: Orlando Andico To: Gurunandan R Bhat cc: Toby Ounsted , "djgpp AT delorie DOT com" Subject: Rotating a point (x,y). In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Tue, 10 Sep 1996, Gurunandan R Bhat wrote: [snip] > > Not wishing to go too far off topic, but does anyone have any C code > > (and/or formulae) for rotating a point (x,y) around the origin(0,0) by a > > fixed number of degrees?? I'm sure I did this in Maths at school, but it was > > a _LONG_ time ago... [snip] > > if you take a point (x,y) and rotate it anti clockwise about the origin by > an angle t, the new point (x',y') is gotten like so: > > x' = x * cos(t) + y * sin(t) > y' = - x * sin(t) + y * cos(t) > > if you want to rotate it clockwise by the same angle you just replace t by > -t. in a program, if you want to rotate it repeatedly by a fixed amount > dt, starting from t = 0.0, (to get a cicle or an ellipse say) you could > consider the following pseudo-code: > > dc = cos(dt); > ds = sin(dt); > x = r; > y = 0.0; > begin loop > { temp = x * dc + y * ds; > y = - x * ds + y * dc; > x = temp; > } > end loop > > this way you can get away by evaluating trignometric functions only once. Another fairly common technique (assuming you're going to use the point rotations for a low-precision application like a game or something) is to precalculate the sines and cosines for a given angular resolution. e.g. if 1-degree resolution is all you need, a 360-element array is all you need for the sine, less if you take advantage of symmetry. You can even "normalize" it like so: double deg_per_rad = 360.0 / (2 * M_PI); double radian, sine; signed int sine_table[360]; signed int scale_factor; int deg; scale_factor = 1 << 31; /* 2**30 or half the full-scale of an int */ for (deg = 0; deg < 360; deg++) { radian = deg / deg_per_rad; sine = sin (radian); sine_table[deg] = sine * scale_factor; } This way, when the sine/cosine is maximum (+1 or -1) the integer array contains 2^30, so the entire range (+1, -1) covers the range of an int. So you can get away later with only integer multiplies, a major savings even in these days of cheap and fast FPU's. This technique is quite well known in digital signal processing (most of the earlier DSP's, and a lot of those used today, are fixed-point integer units). Because whatever you say about Intel's PPro FPU, integer math will still be faster than FP math. The precision really depends on the application. For example, if you are doing 256-point FFT's, you won't gain too much by having even 1-degree angular resolution, because the granularity of the FFT is less than that. So even allegedly "higher math" problems can be efficiently solved using integer techniques.