123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- /*
- * ===========================================================================
- *
- * Wolf3D Browser Version GPL Source Code
- * Copyright (C) 2012 id Software LLC, a ZeniMax Media company.
- *
- * This file is part of the Wolf3D Browser Version GPL Source Code ("Wolf3D Browser Source Code").
- *
- * Wolf3D Browser Source Code 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.
- *
- * Wolf3D Browser Source Code 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 version 2
- * along with Wolf3D Browser Source Code. If not, see <http://www.gnu.org/licenses/>.
- *
- * If you have questions concerning this license, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- *
- * ===========================================================================
- */
- /**
- * @namespace
- * @description Math functions and lookup tables
- */
- Wolf.Math = (function() {
-
- // ------------------------- * LUTs * -------------------------
- var SinTable = [], // [ ANG_360 + ANG_90 + 1 ],
- CosTable = [], // SinTable + ANG_90,
- TanTable = [], //[ ANG_360 + 1 ];
- XnextTable = [], //[ ANG_360 + 1 ],
- YnextTable = [], //[ ANG_360 + 1 ],
- ColumnAngle = [], // [ 640 ]; // ViewAngle=PlayerAngle+ColumnAngle[curcolumn]; /in fines/
-
- // Angle Direction Types & LUTs (Hard Coded! Please do not mess them)
- q_first = 0, q_second = 1, q_third = 2, q_fourth = 3, // quadrant;
- dir4_east = 0, dir4_north = 1, dir4_west = 2, dir4_south = 3, dir4_nodir = 4, // dir4type;
-
- dir8_east = 0, dir8_northeast = 1, dir8_north = 2, dir8_northwest = 3, dir8_west = 4,
- dir8_southwest = 5, dir8_south = 6, dir8_southeast = 7, dir8_nodir = 8, // dir8type;
- dx4dir = [1, 0, -1, 0, 0], // dx & dy based on direction
- dy4dir = [0, 1, 0, -1, 0],
- dx8dir = [1, 1, 0, -1, -1, -1, 0, 1, 0], // dx & dy based on direction
- dy8dir = [0, 1, 1, 1, 0, -1, -1, -1, 0],
- opposite4 = [2, 3, 0, 1, 4],
- opposite8 = [4, 5, 6, 7, 0, 1, 2, 3, 8],
- dir4to8 = [0, 2, 4, 6, 8],
- diagonal = [
- /* 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
- dir4d = [
- [dir4_nodir, dir4_west , dir4_nodir],
- [dir4_south, dir4_nodir, dir4_north],
- [dir4_nodir, dir4_east , dir4_nodir]
- ],
- dir8angle = [Wolf.ANG_0, Wolf.ANG_45, Wolf.ANG_90, Wolf.ANG_135, Wolf.ANG_180, Wolf.ANG_225, Wolf.ANG_270, Wolf.ANG_315, Wolf.ANG_0];
- dir4angle = [Wolf.ANG_0, Wolf.ANG_90, Wolf.ANG_180, Wolf.ANG_270, Wolf.ANG_0];
- /**
- * @private
- * @description Build LUTs, etc.
- */
- function buildTables() {
- var angle, tanfov2, tanval, value,
- n;
- for (n = 0; n <= Wolf.ANG_90 ; ++n) {
- angle = Wolf.FINE2RAD(n);
- value = Math.sin(angle);
- SinTable[n] = SinTable[Wolf.ANG_180 - n] = SinTable[n + Wolf.ANG_360] = value;
- SinTable[Wolf.ANG_180 + n] = SinTable[Wolf.ANG_360 - n] = -value;
- }
- for (n = 0; n <= SinTable.length - Wolf.ANG_90; ++n) {
- CosTable[n] = SinTable[n + Wolf.ANG_90];
- }
- for (n = 0; n <= Wolf.ANG_360 ; ++n) {
- angle = Wolf.FINE2RAD(n); //angle is in radians, n is in FINEs
- if (n == Wolf.ANG_90 || n == Wolf.ANG_270) {
- TanTable[n] = Math.tan(Wolf.FINE2RAD(n - 0.5)); // infinity
- YnextTable[n] = (Wolf.FLOATTILE * Math.tan(Wolf.FINE2RAD(n - 0.5)))>>0; // infinity
- } else {
- TanTable[n] = Math.tan(angle);
- YnextTable[n] = (Wolf.FLOATTILE * Math.tan(angle))>>0;
- }
- if(n == Wolf.ANG_0 || n == Wolf.ANG_360) {
- XnextTable[n] = (Wolf.FLOATTILE / Math.tan(Wolf.FINE2RAD(n + 0.5)))>>0; // infinity
- } else if (n == Wolf.ANG_180) {
- XnextTable[n] = (Wolf.FLOATTILE / Math.tan(Wolf.FINE2RAD(n - 0.5)))>>0; // -infinity
- } else if (n == Wolf.ANG_90 || n == Wolf.ANG_270) {
- XnextTable[n] = 0;
- } else {
- XnextTable[n] = (Wolf.FLOATTILE / Math.tan(angle))>>0;
- }
- }
- tanfov2 = (Math.tan(Wolf.DEG2RAD((calcFov(75, Wolf.XRES, Wolf.YRES) / 2.0)))) * (Wolf.XRES / Wolf.YRES);
- for (n = 0; n < Wolf.XRES; ++n) {
- tanval = tanfov2 * (-1.0 + 2.0 * n / (Wolf.XRES-1));
- ColumnAngle[n] = Wolf.RAD2FINE(Math.atan(tanval)) >> 0;
- }
- Wolf.Random.init(1); // random number generators
- return 1;
- }
- /**
- * @description Calculate the field of view.
- * @memberOf Wolf.Math
- * @param {number} fovX Must be within 1 and 179 degrees.
- * @param {number} width Width of viewing area.
- * @param {number} height Height of viewing area.
- * @returns {number} The field of view in degrees.
- */
-
- function calcFov(fovX, width, height) {
- if (fovX < 1 || fovX > 179) {
- throw Error("Bad fov: " + fovX );
- }
- return Wolf.RAD2DEG(Math.atan(height / (width / Math.tan(fovX / 360 * Math.PI)))) * 2;
- }
- /**
- * @description Clips angle to [0..360] bounds.
- * @memberOf Wolf.Math
- * @param {number} alpha Angle in degrees.
- * @returns {number} Normalized angle.
- */
- function normalizeAngle(alpha) {
- if (alpha > Wolf.ANG_360) {
- alpha %= Wolf.ANG_360;
- }
- if (alpha < Wolf.ANG_0) {
- alpha = Wolf.ANG_360 - (-alpha) % Wolf.ANG_360;
- }
- return alpha;
- }
- /**
- * @description Get quadrant.
- * @memberOf Wolf.Math
- * @param {number} angle Radian angle.
- * @returns {number}
- */
- function getQuadrant(angle) {
- angle = Wolf.Angle.normalize(angle);
- if (angle < Math.PI / 2) {
- return q_first;
- } else if (angle < Math.PI) {
- return q_second;
- } else if (angle < 3 * Math.PI / 2) {
- return q_third;
- } else {
- return q_fourth;
- }
- }
- /**
- * @description Get 4 point direction.
- * @memberOf Wolf.Math
- * @param {number} angle Radian angle.
- * @returns {number} Directional point.
- */
- function get4dir(angle) {
- angle = Wolf.Angle.normalize(angle + Math.PI / 4);
- if (angle < Math.PI / 2) {
- return dir4_east;
- } else if( angle < Math.PI ) {
- return dir4_north;
- } else if( angle < 3 * Math.PI / 2 ) {
- return dir4_west;
- } else {
- return dir4_south;
- }
- }
- /**
- * @description Get 8 point direction.
- * @memberOf Wolf.Math
- * @param {number} angle Radian angle.
- * @returns {number} Directional point.
- */
- function get8dir(angle) {
- angle = Wolf.Angle.normalize(angle + Math.PI / 12);
- if ( angle <= (Math.PI / 4)) {
- return dir8_east;
- } else if (angle < (Math.PI / 2)) {
- return dir8_northeast;
- } else if (angle <= (3 * Math.PI / 4)) {
- return dir8_north;
- } else if (angle < Math.PI) {
- return dir8_northwest;
- } else if (angle <= (5 * Math.PI / 4)) {
- return dir8_west;
- } else if (angle < (3 * Math.PI / 2)) {
- return dir8_southwest;
- } else if (angle <= (7 * Math.PI / 4)) {
- return dir8_south;
- } else {
- return dir8_southeast;
- }
- }
- /**
- * @description calculates distance between a point (x, y) and a line.
- * @memberOf Wolf.Math
- * @param {number} x X coord of point
- * @param {number} y Y coord of point
- * @param {number} a Line angle in degrees
- * @returns {number} Distance
- */
- function point2LineDist(x, y, a) {
- return Math.abs( (x * SinTable[a] - y * CosTable[a]) >> 0);
- }
- /**
- * @description Calculates line length to the point nearest to (poin).
- * @memberOf Wolf.Math
- * @param {number} x X coord of point
- * @param {number} y Y coord of point
- * @param {number} a Line angle in degrees
- * @returns {number} Distance
- */
- function lineLen2Point( x, y, a) {
- return (x * CosTable[a] + y * SinTable[a]) >> 0;
- }
- /*
- point2 = {x,y}
- / |
- / |
- / |
- /a______|----------> x
- point1 = {x, y}
- */
- /**
- * @description Returns angle in radians
- * @memberOf Wolf.Math
- * @param {number} x X coord of point
- * @param {number} y Y coord of point
- * @param {number} a Line angle in degrees
- * @returns {number} Distance
- */
- function transformPoint(point1X, point1Y, point2X, point2Y) {
- var angle = Math.atan2(point1Y - point2Y, point1X - point2X);
- return Wolf.Angle.normalize(angle);
- }
- buildTables();
- return {
- calcFov : calcFov,
- normalizeAngle : normalizeAngle,
- getQuadrant : getQuadrant,
- get4dir : get4dir,
- get8dir : get8dir,
- point2LineDist : point2LineDist,
- lineLen2Point : lineLen2Point,
- transformPoint : transformPoint,
-
- SinTable : SinTable,
- CosTable : CosTable,
- TanTable : TanTable,
- XnextTable : XnextTable,
- YnextTable : YnextTable,
- ColumnAngle : ColumnAngle,
-
- dir4_east : dir4_east,
- dir4_north : dir4_north,
- dir4_west : dir4_west,
- dir4_south : dir4_south,
- dir4_nodir : dir4_nodir,
- dir8_east : dir8_east,
- dir8_northeast : dir8_northeast,
- dir8_north : dir8_north,
- dir8_northwest : dir8_northwest,
- dir8_west : dir8_west,
- dir8_southwest : dir8_southwest,
- dir8_south : dir8_south,
- dir8_southeast : dir8_southeast,
- dir8_nodir : dir8_nodir,
- dx4dir : dx4dir,
- dy4dir : dy4dir,
- dx8dir : dx8dir,
- dy8dir : dy8dir,
- dir4angle : dir4angle,
- dir8angle : dir8angle,
- dir4to8 : dir4to8,
- opposite4 : opposite4,
- opposite8 : opposite8,
- diagonal : diagonal
- };
- })();
|