123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- /*
- Copyright (C) 2004 Michael Liebscher
- Copyright (C) 2000 by DarkOne the Hacker
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- /*
- * wolf_math.c: Wolfenstein 3-D math routines.
- *
- * Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
- * Date: 2004
- *
- * Acknowledgement:
- * This code was derived from NewWolf, and was originally
- * written by DarkOne the Hacker.
- *
- *
- */
- #include "../wolfiphone.h"
- #define XRES 640
- #define YRES 480
- // ------------------------- * LUTs * -------------------------
- double SinTable[ ANG_360 + ANG_90 + 1 ],
- *CosTable = SinTable + ANG_90,
- TanTable[ ANG_360 + 1 ];
- int XnextTable[ ANG_360 + 1 ],
- YnextTable[ ANG_360 + 1 ];
- int ColumnAngle[ 640 ]; // ViewAngle=PlayerAngle+ColumnAngle[curcolumn]; /in fines/
- char dx4dir[5]={1, 0, -1, 0, 0}; // dx & dy based on direction
- char dy4dir[5]={0, 1, 0, -1, 0};
- char dx8dir[9]={1, 1, 0, -1, -1, -1, 0, 1, 0}; // dx & dy based on direction
- char dy8dir[9]={0, 1, 1, 1, 0, -1, -1, -1, 0};
- dir4type opposite4[5]={2, 3, 0, 1, 4};
- dir8type opposite8[9]={4, 5, 6, 7, 0, 1, 2, 3, 8};
- dir8type dir4to8[5]={0, 2, 4, 6, 8};
- dir8type diagonal[9][9]=
- {
- /* east */ {dir8_nodir, dir8_nodir, dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southeast, dir8_nodir, dir8_nodir},
- {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
- /* north */ {dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
- {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
- /* west */ {dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir},
- {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
- /* south */ {dir8_southeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
- {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
- {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir}
- };
- // dir of delta tooks dx{-1|0|1}+1 & dy{-1|0|1}+1 and give direction
- dir4type dir4d[3][3]={{dir4_nodir, dir4_west , dir4_nodir},
- {dir4_south, dir4_nodir, dir4_north},
- {dir4_nodir, dir4_east , dir4_nodir}};
- int dir8angle[9]={ANG_0, ANG_45, ANG_90, ANG_135, ANG_180, ANG_225, ANG_270, ANG_315, ANG_0};
- int dir4angle[5]={ANG_0, ANG_90, ANG_180, ANG_270, ANG_0};
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC int G_Build_Tables( void )
- {
- double angle, tanfov2, tanval, value;
- int n;
- for( n = 0 ; n <= ANG_90 ; ++n )
- {
- angle = FINE2RAD( n );
- value = sin( angle );
- SinTable[ n ] = SinTable[ ANG_180 - n ] = SinTable[ n + ANG_360 ] = value;
- SinTable[ ANG_180 + n ] = SinTable[ ANG_360 - n ] = -value;
- }
- for( n = 0 ; n <= ANG_360 ; ++n )
- {
- angle = FINE2RAD( n ); //angle is in radians, n is in FINEs
- if( n == ANG_90 || n == ANG_270 )
- {
- TanTable[ n ] = tan( FINE2RAD( n - 0.5 ) ); // infinity
- YnextTable[ n ] = (int)(FLOATTILE * tan( FINE2RAD( n - 0.5 ) )); // infinity
- }
- else
- {
- TanTable[ n ] = tan( angle );
- YnextTable[ n ] = (int)(FLOATTILE * tan( angle ));
- }
- if( n == ANG_0 || n == ANG_360 )
- XnextTable[ n ] = (int)(FLOATTILE / tan( FINE2RAD( n + 0.5 ) )); // infinity
- else if( n == ANG_180 )
- XnextTable[ n ] = (int)(FLOATTILE / tan(FINE2RAD( n - 0.5 ) )); // -infinity
- else if( n == ANG_90 || n == ANG_270 )
- XnextTable[ n ] = 0;
- else
- XnextTable[ n ] = (int)(FLOATTILE / tan( angle ));
- }
- tanfov2 = TanDgr( CalcFov( 75, XRES, YRES) / 2.0 ) * ((float)XRES / (float)YRES );
- for( n = 0 ; n < XRES ; ++n )
- {
- tanval = tanfov2 * (-1.0 + 2.0 * (double)n / (double)(XRES-1) );
- ColumnAngle[ n ] = (int)RAD2FINE( atan( tanval ) );
- }
- US_InitRndT( 1 ); // random number generators
- return 1;
- }
- /*
- -----------------------------------------------------------------------------
- Function: NormalizeAngle -clips angle to [0..360] bounds.
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC int NormalizeAngle( int alpha )
- {
- if( alpha > ANG_360 )
- alpha %= ANG_360;
-
- if(alpha<ANG_0)
- alpha = ANG_360 - (-alpha) % ANG_360;
- return alpha;
- }
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC quadrant GetQuadrant( float angle )
- {
- angle = normalize_angle( angle );
- if( angle < M_PI / 2 )
- {
- return q_first;
- }
- else if( angle < M_PI )
- {
- return q_second;
- }
- else if( angle < 3 * M_PI / 2 )
- {
- return q_third;
- }
- else
- {
- return q_fourth;
- }
- }
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC dir4type Get4dir( float angle )
- {
- angle = normalize_angle( angle + M_PI / 4 );
- if( angle < M_PI / 2 )
- {
- return dir4_east;
- }
- else if( angle < M_PI )
- {
- return dir4_north;
- }
- else if( angle < 3 * M_PI / 2 )
- {
- return dir4_west;
- }
- else
- {
- return dir4_south;
- }
- }
- /*
- -----------------------------------------------------------------------------
- Function: Get8dir -Get 8 point direction.
- Parameters: angle -[in] Radian angle.
- Returns: Directional point.
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC dir8type Get8dir( float angle )
- {
- angle = normalize_angle( angle + M_PI / 12 );
- if( angle <= (M_PI / 4) )
- {
- return dir8_east;
- }
- else if( angle < (M_PI / 2) )
- {
- return dir8_northeast;
- }
- else if( angle <= (3 * M_PI / 4) )
- {
- return dir8_north;
- }
- else if( angle < M_PI )
- {
- return dir8_northwest;
- }
- else if( angle <= (5 * M_PI / 4) )
- {
- return dir8_west;
- }
- else if( angle < (3 * M_PI / 2) )
- {
- return dir8_southwest;
- }
- else if( angle <= (7 * M_PI / 4) )
- {
- return dir8_south;
- }
- else
- {
- return dir8_southeast;
- }
- }
- /*
- -----------------------------------------------------------------------------
- Function: Point2LineDist -calculates distance between a point (x, y) and
- a line.
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC int Point2LineDist( int x, int y, int a )
- {
- return ABS( (int)(x * SinTable[ a ] - y * CosTable[ a ]) );
- }
- /*
- -----------------------------------------------------------------------------
- Function: LineLen2Point -Calculates line length to the point nearest to (poin)
- Parameters:
- Returns:
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC int LineLen2Point( int x, int y, int a )
- {
- return (int)(x * CosTable[ a ] + y * SinTable[ a ] );
- }
- /*
- -----------------------------------------------------------------------------
- Function:
- Parameters:
- Returns:
- Notes:
- Function returns angle in radians
- point2 = {x,y}
- / |
- / |
- / |
- /a______|----------> x
- point1 = {x, y}
- -----------------------------------------------------------------------------
- */
- PUBLIC float TransformPoint( double Point1X, double Point1Y, double Point2X, double Point2Y )
- {
- float angle;
- angle = atan2( Point1Y - Point2Y, Point1X - Point2X );
-
- return normalize_angle( angle );
- }
|