delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/09/10/17:36:41

Date: Wed, 11 Sep 1996 03:36:41 +0800 (GMT)
From: Orlando Andico <orly AT gibson DOT eee DOT upd DOT edu DOT ph>
To: Gurunandan R Bhat <grbhat AT unigoa DOT ernet DOT in>
cc: Toby Ounsted <Toby AT viglen DOT co DOT uk>, "djgpp AT delorie DOT com" <djgpp AT delorie DOT com>
Subject: Rotating a point (x,y).
In-Reply-To: <Pine.LNX.3.91.960910214845.3761A-100000@aditya.unigoa.ernet.in>
Message-ID: <Pine.SGI.3.93.960911032734.2210A-100000@gibson.eee.upd.edu.ph>
MIME-Version: 1.0

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.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019