Mercurial > hg > aim92
diff model/atan.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/model/atan.c Fri May 20 15:19:45 2011 +0100 @@ -0,0 +1,103 @@ +/* + Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 + =========================================================================== + + Permission to use, copy, modify, and distribute this software without fee + is hereby granted for research purposes, provided that this copyright + notice appears in all copies and in all supporting documentation, and that + the software is not redistributed for any fee (except for a nominal shipping + charge). Anyone wanting to incorporate all or part of this software in a + commercial product must obtain a license from the Medical Research Council. + + The MRC makes no representations about the suitability of this + software for any purpose. It is provided "as is" without express or implied + warranty. + + THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE + A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include <stdio.h> +#include <math.h> + +#include "stitch.h" + +#define OUTPUT_SCALE 360 + +#ifdef TEST + +#define TwoPi (3.1415926535*2) + + +main( argc, argv ) +int argc ; +char *argv[] ; +{ + double deg ; + + printf( "hello\n" ); + + for( deg = 0 ; deg < TwoPi/2 ; deg += TwoPi/90001. ) + if( (int) ( atan2( sin( deg ), cos( deg ) )/TwoPi*OUTPUT_SCALE + 0.5 ) != iatan2( (int) ( sin(deg)*1000 ), (int) ( cos(deg)*1000 ) ) ) + printf( " %f %d\n", atan2( sin( deg ), cos( deg ) )/TwoPi*OUTPUT_SCALE, iatan2( (int) ( sin(deg)*1000 ), (int) ( cos(deg)*1000 ) ) ) ; + + for( ; deg < TwoPi ; deg += TwoPi/90001. ) + if( (int) ( atan2( sin( deg ), cos( deg ) )/TwoPi*OUTPUT_SCALE - 0.5 ) != iatan2( (int) ( sin(deg)*1000 ), (int) ( cos(deg)*1000 ) ) ) + printf( " %f %d\n", atan2( sin( deg ), cos( deg ) )/TwoPi*OUTPUT_SCALE, iatan2( (int) ( sin(deg)*1000 ), (int) ( cos(deg)*1000 ) ) ) ; + + +} + +#endif + +iatan2( y, x ) +int y, x ; +{ + static int table_bits = 14 ; + static unsigned table_size ; + static short *atan_table = ( short * ) 0 ; + double two_phi ; + int i ; + + if( atan_table == ( short * ) 0 ) { + + table_size = 1 << table_bits ; + + atan_table = ( short * ) stitch_malloc( sizeof ( *atan_table ) * ( table_size + 1 ), "Making atan lookup table" ) ; + + two_phi = atan( 1. ) * 8. ; + + for( i=0 ; i <= table_size ; i++ ) + atan_table[ i ] = atan( ( double ) i / ( table_size ) ) / two_phi * OUTPUT_SCALE + 0.5 ; + } + + if( x != 0 || y != 0 ) + if( y > 0 ) + if( x > 0 ) + if( x > y ) + return( atan_table[ ( ( y << table_bits + ( table_size >> 1 ) ) ) / x ] ) ; + else + return( ( OUTPUT_SCALE >> 2 ) - atan_table[ ( ( x << table_bits + ( table_size >> 1 ) ) ) / y ] ) ; + else + if( -x < y ) + return( ( OUTPUT_SCALE >> 2 ) + atan_table[ ( ( -x << table_bits + ( table_size >> 1 ) ) ) / y ] ) ; + else + return( ( OUTPUT_SCALE >> 1 ) - atan_table[ ( ( y << table_bits + ( table_size >> 1 ) ) ) / -x ] ) ; + else + if( x < 0 ) + if( -x > -y ) + return( -( OUTPUT_SCALE >> 1 ) + atan_table[ ( ( -y << table_bits + ( table_size >> 1 ) ) ) / -x ] ) ; + else + return( -( OUTPUT_SCALE >> 2 ) - atan_table[ ( ( -x << table_bits + ( table_size >> 1 ) ) ) / -y ] ) ; + else + if( x < -y ) + return( -( OUTPUT_SCALE >> 2 ) + atan_table[ ( ( x << table_bits + ( table_size >> 1 ) ) ) / -y ] ) ; + else + return( - atan_table[ ( ( -y << table_bits + ( table_size >> 1 ) ) ) / x ] ) ; + else + return( 99 ) ; +}