Go to notes and algorithms index. ~ Go to home page.

gradient_8_to_sine_8() and gradient_8_to_cosine_8()


Integer version.

Return the sine or cosine for a supplied gradient.

Normally you supply an angle to a sine or cosine function, but sometimes you just have a gradient, especially in computer game programming where you might only know the co-ordinate of a vector -- in which case you can just do y/x or x/y and find its gradient. So these two functions cut-out the middle man (so you don't have to convert to an angle first) saving a bit of CPU time.

This is an integer maths function and input and output values are multiplied by 256. The 8's in the names of the functions simply refer to that fact that they are eight bit accuracy (i.e. *256). So if you want the sine of gradient 0.5 then do:-
sin8 = gradient_8_to_sine_8( 128 );

The following functions will only return sine or cosine for gradients -1 (*256) to +1 (*256) (equivelent to -45 degrees to + 45 degrees) because you can nearly always lay your hand on a gradient within this range - if necessary you can use the inverse of your gradient (perhaps do x/y instead of y/x for example). In a right angled triangle there is always one less than or equal to 45 degrees. It's best to use gradients in this range because the results are more accurate and you don't have to have huge look-up tables which would need to be horribly detailed for the higher gradients to get a decent result.
tip: If you do have to use the inverse gradient to the one you intended (so that you're within the required range) then just supply it to the cosine function instead of the sine function, or visa versa, and you'll get the answer you first wanted....this is because, for example, the sine of 10 degrees is the same as the cosine of its (complementary angle) 80 degrees (and the gradient of 10 degrees is the same as one over the gradient of 80 degrees) -- you see?

If you need to see diagnostic messages (especially useful when in the initial development stages of a game) then do #define DIAGS 1 at the top of your source file and write yourself and err() routine to display the error number or replace the err() calls with a printf() message.



static const unsigned char gradient_8_sine_8_table[257] =
   {
     0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
    16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
    32,  33,  34,  35,  36,  37,  38,  39,  40,  40,  41,  42,  43,  44,  45,  46,
    47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  57,  58,  59,  60,  61,
    62,  63,  64,  65,  66,  67,  68,  68,  69,  70,  71,  72,  73,  74,  75,  75,
    76,  77,  78,  79,  80,  81,  82,  82,  83,  84,  85,  86,  87,  87,  88,  89,
    90,  91,  92,  92,  93,  94,  95,  96,  96,  97,  98,  99, 100, 100, 101, 102,
   103, 103, 104, 105, 106, 106, 107, 108, 109, 109, 110, 111, 112, 112, 113, 114,
   114, 115, 116, 117, 117, 118, 119, 119, 120, 121, 121, 122, 123, 124, 124, 125,
   126, 126, 127, 127, 128, 129, 129, 130, 131, 131, 132, 133, 133, 134, 134, 135,
   136, 136, 137, 137, 138, 139, 139, 140, 140, 141, 142, 142, 143, 143, 144, 144,
   145, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 152, 152, 153, 153,
   154, 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, 159, 160, 160, 160, 161,
   161, 162, 162, 163, 163, 164, 164, 165, 165, 166, 166, 166, 167, 167, 168, 168,
   169, 169, 169, 170, 170, 171, 171, 172, 172, 172, 173, 173, 174, 174, 174, 175,
   175, 175, 176, 176, 177, 177, 177, 178, 178, 178, 179, 179, 180, 180, 180, 181,
   181
   };  // ... this array was output from a program: GRAD_SIN.BAS  (Jon P)

static const unsigned char gradient_8_cosine_8_table[257] =
   {
   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254,
   254, 254, 254, 254, 254, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252,
   252, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 249, 249, 249, 249, 249,
   248, 248, 248, 248, 247, 247, 247, 247, 246, 246, 246, 246, 245, 245, 245, 245,
   244, 244, 244, 244, 243, 243, 243, 242, 242, 242, 242, 241, 241, 241, 240, 240,
   240, 239, 239, 239, 238, 238, 238, 237, 237, 237, 237, 236, 236, 236, 235, 235,
   235, 234, 234, 234, 233, 233, 232, 232, 232, 231, 231, 231, 230, 230, 230, 229,
   229, 229, 228, 228, 228, 227, 227, 226, 226, 226, 225, 225, 225, 224, 224, 223,
   223, 223, 222, 222, 222, 221, 221, 220, 220, 220, 219, 219, 219, 218, 218, 217,
   217, 217, 216, 216, 216, 215, 215, 214, 214, 214, 213, 213, 212, 212, 212, 211,
   211, 211, 210, 210, 209, 209, 209, 208, 208, 207, 207, 207, 206, 206, 206, 205,
   205, 204, 204, 204, 203, 203, 202, 202, 202, 201, 201, 201, 200, 200, 199, 199,
   199, 198, 198, 198, 197, 197, 196, 196, 196, 195, 195, 195, 194, 194, 193, 193,
   193, 192, 192, 192, 191, 191, 190, 190, 190, 189, 189, 189, 188, 188, 187, 187,
   187, 186, 186, 186, 185, 185, 185, 184, 184, 184, 183, 183, 182, 182, 182, 181,
   181
   };  // ... this array was output from a program: GRAD_SIN.BAS  (Jon P)
   
long gradient_8_to_sine_8( long p_gradient_8 )
   {
   // This routine accepts a gradient between -1.0 * 256 and 1.0 * 256
   // i.e. -256 to 256.   The gradient is equiv to the angle range
   // -45 degrees to 45 degrees..
   //
   // A sine is returned (multiplied by 256)
   // The sine is either negative or positive ... the same sign as the
   // gradient.
   //
   // (V1.0  Jon P      27-Nov-2001)
   //
   register long abs_gradient_8;
   
   abs_gradient_8 = p_gradient_8;
   if ( abs_gradient_8 < 0 ) abs_gradient_8 = 0 - abs_gradient_8;
   
   #if DIAGS
      if ( abs_gradient_8 > 260 ) err( 4033 );
      // ...error - p_gradient_8 is supposed to be between
      //  -256 and 256 (equiv of -45 to 45 degrees)
   #endif

   if ( abs_gradient_8 > 256 ) abs_gradient_8 = 256;
   
   if ( p_gradient_8 >= 0 )
      return gradient_8_sine_8_table[abs_gradient_8];
   else
      return 0 - gradient_8_sine_8_table[abs_gradient_8];
   }


long gradient_8_to_cosine_8( long p_gradient_8 )
   {
   // This routine accepts a gradient between -1.0 * 256 and 1.0 * 256
   // i.e. -256 to 256.   The gradient is equiv to the angle range
   // -45 degrees to 45 degrees..
   //
   // A cosine is returned (multiplied by 256)
   // The cosine is always returned as positive ... nomatter what the sign of
   // the gradient.
   //
   // (V1.0  Jon P   27-Nov-2001)
   //
   register long abs_gradient_8;
   
   abs_gradient_8 = p_gradient_8;
   if ( abs_gradient_8 < 0 ) abs_gradient_8 = 0 - abs_gradient_8;
   
   #if DIAGS
      if ( abs_gradient_8 > 260 ) err( 4034 );
      // ...error - p_gradient_8 is supposed to be between
      //  -256 and 256 (equiv of -45 to 45 degrees)
   #endif

   if ( abs_gradient_8 > 256 ) abs_gradient_8 = 256;
   
   return gradient_8_cosine_8_table[abs_gradient_8];
   }