Rotating a Weather Map
by Robert D. Grappel

Figure 3:

(a)
N2 = (N/2) + 1          center point of a map edge
NN = 0.5 - N2           adjust to center of a given pixel
FOR I = 1 TO N
t = I + NN              center-point pixel coordinate
    CC[I] = t * C       pre-compute Cosine table
        SS[I] = t * S   pre-compute Sine table

(b)
Xrot = CC[X] + SS[Y]
Yrot = CC[Y] - SS[X]


Figure 4:

FOR I = 1 TO N              loop through all the map rows
    Crow = N2 + CC[I]       factor N2 to move the center point
    Srow = N2 - SS[I]       note the minus sign
    FOR J = 1 TO N          loop through all the map columns
        Xrot = Crow + SS[J]
        Yrot = Srow + CC[J]
        output_map[Xrot][Yrot] = input_map[I][J]

Listing One
/* Function to rotate a weather map through an arbitrary angle.
   Arguments: pointer to square input map.
              pointer to square rotated output map.
              size of maps in pixels-per-side.
              rotation angle (in degrees clockwise from North).
   Note: both maps do not use the zero'th row or column.
         both maps sized a maximum of MSIZE * MSIZE */

#include <stdio.h>
#include <math.h>
#include <string.h>

#define MSIZE 258
#define PI 3.141592653

void rotate_map(inmap,outmap,nij,angle) int nij; double angle;
     char inmap[MSIZE][MSIZE],outmap[MSIZE][MSIZE];
{
   char * optr;
   int i,j,nijh,x,y;
   double n0,x0,s,c,cc0,ss0,s0[MSIZE],c0[MSIZE];

   memset(outmap,0,MSIZE*MSIZE);    /* clear output map */ 
   nijh = (nij / 2) + 1;            /* midpoint of the map */
   angle *= (-PI / 180.0);          /* convert neg. angle to radians */
   s = sin(angle);  
   c = cos(angle);
   n0 = 0.5 - nijh;
   for (i=1; i <= nij; i++)
   { /* precompute sine and cosine tables */
       x0 = (double)i + n0;
       c0[i] = x0 * c;  
       s0[i] = x0 * s;
   }
   for (i=1; i <= nij; i++)
   {
       cc0 = nijh + c0[i];  
       ss0 = nijh - s0[i];
       optr = &outmap[i][0];
       for (j=1; j <= nij; j++)
       {
           x = cc0 + s0[j];
           if ((x < 0) || (x > nij)) continue;
           y = ss0 + c0[j];
           if ((y < 0) || (y > nij)) continue;
           optr[j] = inmap[x][y];
       }
   }
}
        


2


