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

distance_to_chord()


Integer Version

Find the distance from the centre of a circle to the centre of a chord line by supplying the chord length (or actually half the chord length) and the circle radius.

Alternatively this could be though-of as finding the unknown length of a side of a right angled triangle when you know the opposite or adjacent side's length and the hypotenus's length.

if you want to diagnose problems in your program when calling this routine then #define DIAGS 1 at the top of the source file and problems will be reported. Also either write yourself an err() routine or replace ther err() calls with printf() messages.


static const unsigned char centre_to_chord_over_radius_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, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252,
   251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 249, 249, 249, 249, 248, 248,
   248, 248, 247, 247, 247, 247, 246, 246, 246, 245, 245, 245, 244, 244, 244, 244,
   243, 243, 243, 242, 242, 241, 241, 241, 240, 240, 240, 239, 239, 239, 238, 238,
   237, 237, 236, 236, 236, 235, 235, 234, 234, 233, 233, 233, 232, 232, 231, 231,
   230, 230, 229, 229, 228, 228, 227, 227, 226, 226, 225, 225, 224, 223, 223, 222,
   222, 221, 221, 220, 219, 219, 218, 218, 217, 216, 216, 215, 214, 214, 213, 212,
   212, 211, 210, 210, 209, 208, 207, 207, 206, 205, 204, 204, 203, 202, 201, 201,
   200, 199, 198, 197, 197, 196, 195, 194, 193, 192, 191, 191, 190, 189, 188, 187,
   186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 172, 170,
   169, 168, 167, 166, 165, 163, 162, 161, 160, 159, 157, 156, 155, 153, 152, 151,
   149, 148, 146, 145, 143, 142, 140, 139, 137, 136, 134, 133, 131, 129, 127, 126,
   124, 122, 120, 118, 116, 114, 112, 110, 108, 106, 104, 102,  99,  97,  94,  92,
    89,  86,  83,  81,  77,  74,  71,  67,  63,  59,  55,  50,  45,  39,  32,  23,
     0,
   };  // ... this array was output from a program: notes_hash\021.BAS  (Jon P)


long distance_to_chord( long p_half_chord_length, long p_radius )
   {
   // Jon P  V1.0   28-Nov-2001
   //
   // This function will return the distance from the centre of a circle to
   // the centre of a chord line within that same circle.  All that needs to
   // be specified to this function is half the length of the chord line,
   // and the circle's radius.
   //
   // WARNING: This Function becomes inaccurate when p_half_chord_length
   //          nears the value of p_radius.  When the half chord length is
   //          more than about 85% of the radius then if an accurate result
   //          is required an alternative to calling this routine should be sort.
   // 
   // Since this is a function that works on proportions it does not
   // matter what accuracy the lengths passed as the two parameters have,
   // provided they are the same as each other.  The result will be returned with
   // the same accuracy as the supplied parameters.
   
   register long fraction_8;
   
   #if DIAGS
      if ( p_half_chord_length < 0 )
         { // lengths must be positive...
         err( 4035 );
         return 128;
         }
      if ( p_radius < 0 )
         { // lengths must be positive...
         err( 4036 );
         return 128;
         }
      if ( p_half_chord_length > p_radius + ( p_radius >> 4 ) + 1 )
         { // half chord length is well over the radius length -- so even accounting for
         // inaccuraces this must be an error
         err( 4037 );
         return 255;
         }
   #endif
   
   if ( ( p_half_chord_length >> 22 ) == 0 )
      { // plenty of bits spare to shift-up before division...
      fraction_8 = ( p_half_chord_length << 8 ) / p_radius;
      }
   else
      {
      #if DIAGS
         if ( ( p_radius >> 8 ) == 0 )
            { // A divide by zero would occur in the next equation.
            // This should never happen (it would mean the half chord len was much bigger than the radius)
            err( 4038 );
            return 0;
            }
      #endif
      fraction_8 = p_half_chord_length / ( p_radius >> 8 );
      }
   
   if ( fraction_8 > 256 ) fraction_8 = 256;
   
   if ( p_radius >> 22 == 0 )
      return ( p_radius * centre_to_chord_over_radius_table[fraction_8] ) >> 8;
   else
      return ( p_radius >> 8 ) * centre_to_chord_over_radius_table[fraction_8];
   }