wolf_math.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. Copyright (C) 2004 Michael Liebscher
  3. Copyright (C) 2000 by DarkOne the Hacker
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. /*
  17. * wolf_math.c: Wolfenstein 3-D math routines.
  18. *
  19. * Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
  20. * Date: 2004
  21. *
  22. * Acknowledgement:
  23. * This code was derived from NewWolf, and was originally
  24. * written by DarkOne the Hacker.
  25. *
  26. *
  27. */
  28. #include "../wolfiphone.h"
  29. #define XRES 640
  30. #define YRES 480
  31. // ------------------------- * LUTs * -------------------------
  32. double SinTable[ ANG_360 + ANG_90 + 1 ],
  33. *CosTable = SinTable + ANG_90,
  34. TanTable[ ANG_360 + 1 ];
  35. int XnextTable[ ANG_360 + 1 ],
  36. YnextTable[ ANG_360 + 1 ];
  37. int ColumnAngle[ 640 ]; // ViewAngle=PlayerAngle+ColumnAngle[curcolumn]; /in fines/
  38. char dx4dir[5]={1, 0, -1, 0, 0}; // dx & dy based on direction
  39. char dy4dir[5]={0, 1, 0, -1, 0};
  40. char dx8dir[9]={1, 1, 0, -1, -1, -1, 0, 1, 0}; // dx & dy based on direction
  41. char dy8dir[9]={0, 1, 1, 1, 0, -1, -1, -1, 0};
  42. dir4type opposite4[5]={2, 3, 0, 1, 4};
  43. dir8type opposite8[9]={4, 5, 6, 7, 0, 1, 2, 3, 8};
  44. dir8type dir4to8[5]={0, 2, 4, 6, 8};
  45. dir8type diagonal[9][9]=
  46. {
  47. /* east */ {dir8_nodir, dir8_nodir, dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southeast, dir8_nodir, dir8_nodir},
  48. {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
  49. /* north */ {dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
  50. {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
  51. /* west */ {dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir},
  52. {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
  53. /* south */ {dir8_southeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
  54. {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
  55. {dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir}
  56. };
  57. // dir of delta tooks dx{-1|0|1}+1 & dy{-1|0|1}+1 and give direction
  58. dir4type dir4d[3][3]={{dir4_nodir, dir4_west , dir4_nodir},
  59. {dir4_south, dir4_nodir, dir4_north},
  60. {dir4_nodir, dir4_east , dir4_nodir}};
  61. int dir8angle[9]={ANG_0, ANG_45, ANG_90, ANG_135, ANG_180, ANG_225, ANG_270, ANG_315, ANG_0};
  62. int dir4angle[5]={ANG_0, ANG_90, ANG_180, ANG_270, ANG_0};
  63. /*
  64. -----------------------------------------------------------------------------
  65. Function:
  66. Parameters:
  67. Returns:
  68. Notes:
  69. -----------------------------------------------------------------------------
  70. */
  71. PUBLIC int G_Build_Tables( void )
  72. {
  73. double angle, tanfov2, tanval, value;
  74. int n;
  75. for( n = 0 ; n <= ANG_90 ; ++n )
  76. {
  77. angle = FINE2RAD( n );
  78. value = sin( angle );
  79. SinTable[ n ] = SinTable[ ANG_180 - n ] = SinTable[ n + ANG_360 ] = value;
  80. SinTable[ ANG_180 + n ] = SinTable[ ANG_360 - n ] = -value;
  81. }
  82. for( n = 0 ; n <= ANG_360 ; ++n )
  83. {
  84. angle = FINE2RAD( n ); //angle is in radians, n is in FINEs
  85. if( n == ANG_90 || n == ANG_270 )
  86. {
  87. TanTable[ n ] = tan( FINE2RAD( n - 0.5 ) ); // infinity
  88. YnextTable[ n ] = (int)(FLOATTILE * tan( FINE2RAD( n - 0.5 ) )); // infinity
  89. }
  90. else
  91. {
  92. TanTable[ n ] = tan( angle );
  93. YnextTable[ n ] = (int)(FLOATTILE * tan( angle ));
  94. }
  95. if( n == ANG_0 || n == ANG_360 )
  96. XnextTable[ n ] = (int)(FLOATTILE / tan( FINE2RAD( n + 0.5 ) )); // infinity
  97. else if( n == ANG_180 )
  98. XnextTable[ n ] = (int)(FLOATTILE / tan(FINE2RAD( n - 0.5 ) )); // -infinity
  99. else if( n == ANG_90 || n == ANG_270 )
  100. XnextTable[ n ] = 0;
  101. else
  102. XnextTable[ n ] = (int)(FLOATTILE / tan( angle ));
  103. }
  104. tanfov2 = TanDgr( CalcFov( 75, XRES, YRES) / 2.0 ) * ((float)XRES / (float)YRES );
  105. for( n = 0 ; n < XRES ; ++n )
  106. {
  107. tanval = tanfov2 * (-1.0 + 2.0 * (double)n / (double)(XRES-1) );
  108. ColumnAngle[ n ] = (int)RAD2FINE( atan( tanval ) );
  109. }
  110. US_InitRndT( 1 ); // random number generators
  111. return 1;
  112. }
  113. /*
  114. -----------------------------------------------------------------------------
  115. Function: NormalizeAngle -clips angle to [0..360] bounds.
  116. Parameters:
  117. Returns:
  118. Notes:
  119. -----------------------------------------------------------------------------
  120. */
  121. PUBLIC int NormalizeAngle( int alpha )
  122. {
  123. if( alpha > ANG_360 )
  124. alpha %= ANG_360;
  125. if(alpha<ANG_0)
  126. alpha = ANG_360 - (-alpha) % ANG_360;
  127. return alpha;
  128. }
  129. /*
  130. -----------------------------------------------------------------------------
  131. Function:
  132. Parameters:
  133. Returns:
  134. Notes:
  135. -----------------------------------------------------------------------------
  136. */
  137. PUBLIC quadrant GetQuadrant( float angle )
  138. {
  139. angle = normalize_angle( angle );
  140. if( angle < M_PI / 2 )
  141. {
  142. return q_first;
  143. }
  144. else if( angle < M_PI )
  145. {
  146. return q_second;
  147. }
  148. else if( angle < 3 * M_PI / 2 )
  149. {
  150. return q_third;
  151. }
  152. else
  153. {
  154. return q_fourth;
  155. }
  156. }
  157. /*
  158. -----------------------------------------------------------------------------
  159. Function:
  160. Parameters:
  161. Returns:
  162. Notes:
  163. -----------------------------------------------------------------------------
  164. */
  165. PUBLIC dir4type Get4dir( float angle )
  166. {
  167. angle = normalize_angle( angle + M_PI / 4 );
  168. if( angle < M_PI / 2 )
  169. {
  170. return dir4_east;
  171. }
  172. else if( angle < M_PI )
  173. {
  174. return dir4_north;
  175. }
  176. else if( angle < 3 * M_PI / 2 )
  177. {
  178. return dir4_west;
  179. }
  180. else
  181. {
  182. return dir4_south;
  183. }
  184. }
  185. /*
  186. -----------------------------------------------------------------------------
  187. Function: Get8dir -Get 8 point direction.
  188. Parameters: angle -[in] Radian angle.
  189. Returns: Directional point.
  190. Notes:
  191. -----------------------------------------------------------------------------
  192. */
  193. PUBLIC dir8type Get8dir( float angle )
  194. {
  195. angle = normalize_angle( angle + M_PI / 12 );
  196. if( angle <= (M_PI / 4) )
  197. {
  198. return dir8_east;
  199. }
  200. else if( angle < (M_PI / 2) )
  201. {
  202. return dir8_northeast;
  203. }
  204. else if( angle <= (3 * M_PI / 4) )
  205. {
  206. return dir8_north;
  207. }
  208. else if( angle < M_PI )
  209. {
  210. return dir8_northwest;
  211. }
  212. else if( angle <= (5 * M_PI / 4) )
  213. {
  214. return dir8_west;
  215. }
  216. else if( angle < (3 * M_PI / 2) )
  217. {
  218. return dir8_southwest;
  219. }
  220. else if( angle <= (7 * M_PI / 4) )
  221. {
  222. return dir8_south;
  223. }
  224. else
  225. {
  226. return dir8_southeast;
  227. }
  228. }
  229. /*
  230. -----------------------------------------------------------------------------
  231. Function: Point2LineDist -calculates distance between a point (x, y) and
  232. a line.
  233. Parameters:
  234. Returns:
  235. Notes:
  236. -----------------------------------------------------------------------------
  237. */
  238. PUBLIC int Point2LineDist( int x, int y, int a )
  239. {
  240. return ABS( (int)(x * SinTable[ a ] - y * CosTable[ a ]) );
  241. }
  242. /*
  243. -----------------------------------------------------------------------------
  244. Function: LineLen2Point -Calculates line length to the point nearest to (poin)
  245. Parameters:
  246. Returns:
  247. Notes:
  248. -----------------------------------------------------------------------------
  249. */
  250. PUBLIC int LineLen2Point( int x, int y, int a )
  251. {
  252. return (int)(x * CosTable[ a ] + y * SinTable[ a ] );
  253. }
  254. /*
  255. -----------------------------------------------------------------------------
  256. Function:
  257. Parameters:
  258. Returns:
  259. Notes:
  260. Function returns angle in radians
  261. point2 = {x,y}
  262. / |
  263. / |
  264. / |
  265. /a______|----------> x
  266. point1 = {x, y}
  267. -----------------------------------------------------------------------------
  268. */
  269. PUBLIC float TransformPoint( double Point1X, double Point1Y, double Point2X, double Point2Y )
  270. {
  271. float angle;
  272. angle = atan2( Point1Y - Point2Y, Point1X - Point2X );
  273. return normalize_angle( angle );
  274. }