// FastMath.cpp: implementation of the CFastMath class. // ////////////////////////////////////////////////////////////////////// #include #include "FastMath.h" // This table only works on Little Endian(Byte Order) machine. unsigned short CFastMath::m_FastHeToBi[0x100] = { 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530, 0x4630, 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931, 0x4131, 0x4231, 0x4331, 0x4431, 0x4531, 0x4631, 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932, 0x4132, 0x4232, 0x4332, 0x4432, 0x4532, 0x4632, 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933, 0x4133, 0x4233, 0x4333, 0x4433, 0x4533, 0x4633, 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934, 0x4134, 0x4234, 0x4334, 0x4434, 0x4534, 0x4634, 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935, 0x4135, 0x4235, 0x4335, 0x4435, 0x4535, 0x4635, 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936, 0x4136, 0x4236, 0x4336, 0x4436, 0x4536, 0x4636, 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937, 0x4137, 0x4237, 0x4337, 0x4437, 0x4537, 0x4637, 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938, 0x4138, 0x4238, 0x4338, 0x4438, 0x4538, 0x4638, 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939, 0x4139, 0x4239, 0x4339, 0x4439, 0x4539, 0x4639, 0x3041, 0x3141, 0x3241, 0x3341, 0x3441, 0x3541, 0x3641, 0x3741, 0x3841, 0x3941, 0x4141, 0x4241, 0x4341, 0x4441, 0x4541, 0x4641, 0x3042, 0x3142, 0x3242, 0x3342, 0x3442, 0x3542, 0x3642, 0x3742, 0x3842, 0x3942, 0x4142, 0x4242, 0x4342, 0x4442, 0x4542, 0x4642, 0x3043, 0x3143, 0x3243, 0x3343, 0x3443, 0x3543, 0x3643, 0x3743, 0x3843, 0x3943, 0x4143, 0x4243, 0x4343, 0x4443, 0x4543, 0x4643, 0x3044, 0x3144, 0x3244, 0x3344, 0x3444, 0x3544, 0x3644, 0x3744, 0x3844, 0x3944, 0x4144, 0x4244, 0x4344, 0x4444, 0x4544, 0x4644, 0x3045, 0x3145, 0x3245, 0x3345, 0x3445, 0x3545, 0x3645, 0x3745, 0x3845, 0x3945, 0x4145, 0x4245, 0x4345, 0x4445, 0x4545, 0x4645, 0x3046, 0x3146, 0x3246, 0x3346, 0x3446, 0x3546, 0x3646, 0x3746, 0x3846, 0x3946, 0x4146, 0x4246, 0x4346, 0x4446, 0x4546, 0x4646, }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// unsigned int CFastMath::m_FastSqrtTable[0x10000]; long CFastMath::m_HoldRand = 1L; CFastMath::CFastMath() { } CFastMath::~CFastMath() { } void CFastMath::Init() { unsigned int i; FastSqrtUnion s; for (i=0;i<=0x7FFF;i++) { s.i = (i << 8) | (0x7F << 23); s.f = (float)sqrt(s.f); m_FastSqrtTable[i+0x8000]=(s.i&0x7FFFFF); s.i = (i << 8) | (0x80 << 23); s.f = (float)sqrt(s.f); m_FastSqrtTable[i]=(s.i&0x7FFFFF); } } // // this function returns the equivalent binary value for an individual character specified in the ascii format UCHAR CFastMath::BiToHe( char cBin ) { if( (cBin >= '0') && (cBin <= '9') ) { return ( cBin - '0' ); } else if( (cBin >= 'A') && (cBin <= 'F') ) { return ( cBin - 'A' + 0xA ); } if( (cBin >= 'a') && (cBin <= 'f') ) { return ( cBin -'a' + 0xA ); } return cBin; } void CFastMath::AcToHe(char *szDst, char *szSrc, int iCount) { while( iCount-- ) { *szDst = BiToHe(*szSrc) << 4; *szSrc++; *szDst += BiToHe(*szSrc); *szSrc++; *szDst++; } /* ´å³Ý ¸±¸®Áî ¹öÀü¿¡¼­ ÀÌ ·çƾÀ¸·Î ÄÄÆÄÀÏÇϸé Á¦´ë·Î ÀÛµ¿ÇÏÁö ¾Ê½À´Ï´Ù(szDst¿¡ ¾Æ¹«°Íµµ º¹»ç°¡ ¾ÈµÊ). ´Ù¸¥ ºÐµéÀº ±¦ÂúÀº°¡¿ä? --ÀåÁø¿µ (2002-08-17) // while (iCount--) { // *szDst++ = (BiToHe(*szSrc++) << 4) + BiToHe(*szSrc++); // } */ return; } char CFastMath::StrToHex08(char *szSrc) { char *pStart = szSrc + 2; char cHex = 0; for (int i=0; i<1; i++) { char c1 = BiToHe(*pStart++); c1 <<= (8*(7-i)+4); char c2 = BiToHe(*pStart++); c2 <<= (8*(7-i)); char cRet = c1 + c2; cHex += cRet; } return cHex; } unsigned short CFastMath::StrToHex16(char *szSrc) { char *pStart = szSrc + 2; unsigned short sHex = 0; for (int i=0; i<2; i++) { unsigned short s1 = BiToHe(*pStart++); s1 <<= (8*(1-i)+4); unsigned short s2 = BiToHe(*pStart++); s2 <<= (8*(1-i)); unsigned short sRet = s1 + s2; sHex += sRet; } return sHex; } // convert string to hexadecimal value DWORD CFastMath::StrToHex32(char *szSrc) { char *pStart = szSrc + 2; DWORD dwHex = 0; for (int i=0; i<4; i++) { DWORD dw1 = BiToHe(*pStart++); dw1 <<= (8*(3-i)+4); DWORD dw2 = BiToHe(*pStart++); dw2 <<= (8*(3-i)); DWORD dwRet = dw1 + dw2; dwHex += dwRet; } return dwHex; } // convert string to hexadecimal value __int64 CFastMath::StrToHex64(char *szSrc) { char *pStart = szSrc + 2; __int64 dlHex = 0; for (int i=0; i<8; i++) { __int64 dl1 = BiToHe(*pStart++); dl1 <<= (8*(7-i)+4); __int64 dl2 = BiToHe(*pStart++); dl2 <<= (8*(7-i)); __int64 dlRet = dl1 + dl2; dlHex += dlRet; } return dlHex; } char CFastMath::Atoc( char *szSrc ) { if( strncmp( szSrc, "0x", 2 ) == 0 ) { return StrToHex08( szSrc ); } else { return (char) _ttol( szSrc ); } } // // TCHAR *·Î °íĨ½Ã´Ù! (By Standil) // unsigned short CFastMath::Atos( char *szSrc ) { if( strncmp( szSrc, "0x", 2 ) == 0 ) { return StrToHex16( szSrc ); } else { return _ttoi( szSrc ); } } // // TCHAR *·Î °íĨ½Ã´Ù! (By Standil) // unsigned int CFastMath::Atoi( char *szSrc ) { if( strncmp( szSrc, "0x", 2 ) == 0 ) { return StrToHex32( szSrc ); } else { return _ttol( szSrc ); } } // // TCHAR *·Î °íĨ½Ã´Ù! (By Standil) // _int64 CFastMath::Atol64( char *szSrc ) { if( strncmp( szSrc, "0x", 2 ) == 0 ) { return StrToHex32( szSrc ); } else { return _ttoi64( szSrc ); } } void CFastMath::SRand( unsigned int seed ) { m_HoldRand = (long) seed; } int CFastMath::Rand( void ) { return( ((m_HoldRand = m_HoldRand * 214013L + 2531011L) >> 16) & 0x7FFF ); } /////////////////////////////////////////////////////////////////////////////////////////////// // utility functions // 0 -0x7FFFFFFF. DWORD CFastMath::ComplexRandom(int nExtent) { static unsigned long x = 1; static unsigned long c = 0; static unsigned long a = 2083801278UL; #define addto(rh,rl,ah,al) (rl) = ((rl) + (al)) & 0xFFFFFFFFUL; \ (rh) = ((rh) + (ah) + (((rl) < (al)) ? 1 : 0)) & 0xFFFFFFFFUL unsigned long xl = (x & 0xFFFFUL); unsigned long xh = (x >> 16) & 0xFFFFUL; unsigned long al = (a & 0xFFFFUL); unsigned long ah = (a >> 16) & 0xFFFFUL; unsigned long tmp; x = c; c = 0; tmp = xl * al; addto(c, x, 0, tmp); tmp = xl * ah; addto(c, x, (tmp >> 16), (tmp & 0xFFFFUL) << 16); tmp = xh * ah; addto(c, x, tmp, 1); tmp = xh * al; addto(c, x, (tmp >> 16), (tmp & 0xFFFFUL) << 16); if (nExtent < 1) return 1; return (x % nExtent); // return x & 0x7FFFFFFFUL; } /* _rand From GNU Libc source This algorithm is mentioned in the ISO C standard, here extended for 32 bits. int rand_r (unsigned int *seed) { unsigned int next = *seed; int result; next *= 1103515245; next += 12345; result = (unsigned int) (next / 65536) % 2048; next *= 1103515245; next += 12345; result <<= 10; result ^= (unsigned int) (next / 65536) % 1024; next *= 1103515245; next += 12345; result <<= 10; result ^= (unsigned int) (next / 65536) % 1024; *seed = next; return result; } static double SinTable[] = { 0.000000, 0.017452, 0.034899, 0.052336, 0.069756, 0.087156, 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809, 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372, 0.309017, 0.325568, 0.342020, 0.358368, 0.374607, 0.390731, 0.406737, 0.422618, 0.438371, 0.453990, 0.469472, 0.484810, 0.500000, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576, 0.587785, 0.601815, 0.615661, 0.629320, 0.642788, 0.656059, 0.669131, 0.681998, 0.694658, 0.707107, 0.719340, 0.731354, 0.743145, 0.754710, 0.766044, 0.777146, 0.788011, 0.798636, 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167, 0.866025, 0.874620, 0.882948, 0.891007, 0.898794, 0.906308, 0.913545, 0.920505, 0.927184, 0.933580, 0.939693, 0.945519, 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.974370, 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546, 0.994522, 0.996195, 0.997564, 0.998630, 0.999391, 0.999848, 1.000000, 0.999848, 0.999391, 0.998630, 0.997564, 0.996195, 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627, 0.978148, 0.974370, 0.970296, 0.965926, 0.961262, 0.956305, 0.951057, 0.945519, 0.939693, 0.933580, 0.927184, 0.920505, 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.874620, 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152, 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.754710, 0.743145, 0.731354, 0.719340, 0.707107, 0.694658, 0.681998, 0.669131, 0.656059, 0.642788, 0.629320, 0.615661, 0.601815, 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038, 0.500000, 0.484810, 0.469472, 0.453990, 0.438371, 0.422618, 0.406737, 0.390731, 0.374607, 0.358368, 0.342020, 0.325568, 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951, 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869, 0.104528, 0.087156, 0.069756, 0.052336, 0.034899, 0.017452, 0.000000, -0.017452, -0.034899, -0.052336, -0.069756, -0.087156, -0.104528, -0.121869, -0.139173, -0.156434, -0.173648, -0.190809, -0.207912, -0.224951, -0.241922, -0.258819, -0.275637, -0.292372, -0.309017, -0.325568, -0.342020, -0.358368, -0.374607, -0.390731, -0.406737, -0.422618, -0.438371, -0.453990, -0.469472, -0.484810, -0.500000, -0.515038, -0.529919, -0.544639, -0.559193, -0.573576, -0.587785, -0.601815, -0.615661, -0.629320, -0.642788, -0.656059, -0.669131, -0.681998, -0.694658, -0.707107, -0.719340, -0.731354, -0.743145, -0.754710, -0.766044, -0.777146, -0.788011, -0.798636, -0.809017, -0.819152, -0.829038, -0.838671, -0.848048, -0.857167, -0.866025, -0.874620, -0.882948, -0.891007, -0.898794, -0.906308, -0.913545, -0.920505, -0.927184, -0.933580, -0.939693, -0.945519, -0.951057, -0.956305, -0.961262, -0.965926, -0.970296, -0.974370, -0.978148, -0.981627, -0.984808, -0.987688, -0.990268, -0.992546, -0.994522, -0.996195, -0.997564, -0.998630, -0.999391, -0.999848, -1.000000, -0.999848, -0.999391, -0.998630, -0.997564, -0.996195, -0.994522, -0.992546, -0.990268, -0.987688, -0.984808, -0.981627, -0.978148, -0.974370, -0.970296, -0.965926, -0.961262, -0.956305, -0.951057, -0.945519, -0.939693, -0.933580, -0.927184, -0.920505, -0.913545, -0.906308, -0.898794, -0.891007, -0.882948, -0.874620, -0.866025, -0.857167, -0.848048, -0.838671, -0.829038, -0.819152, -0.809017, -0.798636, -0.788011, -0.777146, -0.766044, -0.754710, -0.743145, -0.731354, -0.719340, -0.707107, -0.694658, -0.681998, -0.669131, -0.656059, -0.642788, -0.629320, -0.615661, -0.601815, -0.587785, -0.573576, -0.559193, -0.544639, -0.529919, -0.515038, -0.500000, -0.484810, -0.469472, -0.453990, -0.438371, -0.422618, -0.406737, -0.390731, -0.374607, -0.358368, -0.342020, -0.325568, -0.309017, -0.292372, -0.275637, -0.258819, -0.241922, -0.224951, -0.207912, -0.190809, -0.173648, -0.156434, -0.139173, -0.121869, -0.104528, -0.087156, -0.069756, -0.052336, -0.034899, -0.017452 }; static double CosTable[] = { 1.000000, 0.999848, 0.999391, 0.998630, 0.997564, 0.996195, 0.994522, 0.992546, 0.990268, 0.987688, 0.984808, 0.981627, 0.978148, 0.974370, 0.970296, 0.965926, 0.961262, 0.956305, 0.951057, 0.945519, 0.939693, 0.933580, 0.927184, 0.920505, 0.913545, 0.906308, 0.898794, 0.891007, 0.882948, 0.874620, 0.866025, 0.857167, 0.848048, 0.838671, 0.829038, 0.819152, 0.809017, 0.798636, 0.788011, 0.777146, 0.766044, 0.754710, 0.743145, 0.731354, 0.719340, 0.707107, 0.694658, 0.681998, 0.669131, 0.656059, 0.642788, 0.629320, 0.615661, 0.601815, 0.587785, 0.573576, 0.559193, 0.544639, 0.529919, 0.515038, 0.500000, 0.484810, 0.469472, 0.453990, 0.438371, 0.422618, 0.406737, 0.390731, 0.374607, 0.358368, 0.342020, 0.325568, 0.309017, 0.292372, 0.275637, 0.258819, 0.241922, 0.224951, 0.207912, 0.190809, 0.173648, 0.156434, 0.139173, 0.121869, 0.104528, 0.087156, 0.069756, 0.052336, 0.034899, 0.017452, 0.000000, -0.017452, -0.034899, -0.052336, -0.069756, -0.087156, -0.104528, -0.121869, -0.139173, -0.156434, -0.173648, -0.190809, -0.207912, -0.224951, -0.241922, -0.258819, -0.275637, -0.292372, -0.309017, -0.325568, -0.342020, -0.358368, -0.374607, -0.390731, -0.406737, -0.422618, -0.438371, -0.453990, -0.469472, -0.484810, -0.500000, -0.515038, -0.529919, -0.544639, -0.559193, -0.573576, -0.587785, -0.601815, -0.615661, -0.629320, -0.642788, -0.656059, -0.669131, -0.681998, -0.694658, -0.707107, -0.719340, -0.731354, -0.743145, -0.754710, -0.766044, -0.777146, -0.788011, -0.798636, -0.809017, -0.819152, -0.829038, -0.838671, -0.848048, -0.857167, -0.866025, -0.874620, -0.882948, -0.891007, -0.898794, -0.906308, -0.913545, -0.920505, -0.927184, -0.933580, -0.939693, -0.945519, -0.951057, -0.956305, -0.961262, -0.965926, -0.970296, -0.974370, -0.978148, -0.981627, -0.984808, -0.987688, -0.990268, -0.992546, -0.994522, -0.996195, -0.997564, -0.998630, -0.999391, -0.999848, -1.000000, -0.999848, -0.999391, -0.998630, -0.997564, -0.996195, -0.994522, -0.992546, -0.990268, -0.987688, -0.984808, -0.981627, -0.978148, -0.974370, -0.970296, -0.965926, -0.961262, -0.956305, -0.951057, -0.945519, -0.939693, -0.933580, -0.927184, -0.920505, -0.913545, -0.906308, -0.898794, -0.891007, -0.882948, -0.874620, -0.866025, -0.857167, -0.848048, -0.838671, -0.829038, -0.819152, -0.809017, -0.798636, -0.788011, -0.777146, -0.766044, -0.754710, -0.743145, -0.731354, -0.719340, -0.707107, -0.694658, -0.681998, -0.669131, -0.656059, -0.642788, -0.629320, -0.615661, -0.601815, -0.587785, -0.573576, -0.559193, -0.544639, -0.529919, -0.515038, -0.500000, -0.484810, -0.469472, -0.453990, -0.438371, -0.422618, -0.406737, -0.390731, -0.374607, -0.358368, -0.342020, -0.325568, -0.309017, -0.292372, -0.275637, -0.258819, -0.241922, -0.224951, -0.207912, -0.190809, -0.173648, -0.156434, -0.139173, -0.121869, -0.104528, -0.087156, -0.069756, -0.052336, -0.034899, -0.017452, -0.000000, 0.017452, 0.034899, 0.052336, 0.069756, 0.087156, 0.104528, 0.121869, 0.139173, 0.156434, 0.173648, 0.190809, 0.207912, 0.224951, 0.241922, 0.258819, 0.275637, 0.292372, 0.309017, 0.325568, 0.342020, 0.358368, 0.374607, 0.390731, 0.406737, 0.422618, 0.438371, 0.453990, 0.469472, 0.484810, 0.500000, 0.515038, 0.529919, 0.544639, 0.559193, 0.573576, 0.587785, 0.601815, 0.615661, 0.629320, 0.642788, 0.656059, 0.669131, 0.681998, 0.694658, 0.707107, 0.719340, 0.731354, 0.743145, 0.754710, 0.766044, 0.777146, 0.788011, 0.798636, 0.809017, 0.819152, 0.829038, 0.838671, 0.848048, 0.857167, 0.866025, 0.874620, 0.882948, 0.891007, 0.898794, 0.906308, 0.913545, 0.920505, 0.927184, 0.933580, 0.939693, 0.945519, 0.951057, 0.956305, 0.961262, 0.965926, 0.970296, 0.974370, 0.978148, 0.981627, 0.984808, 0.987688, 0.990268, 0.992546, 0.994522, 0.996195, 0.997564, 0.998630, 0.999391, 0.999848 }; double as_sin( int degree ) { while( degree < 0 ) degree += 360; degree = degree%360; return SinTable[degree]; } double as_cos( int degree ) { while( degree < 0 ) degree += 360; degree = degree%360; return CosTable[degree]; } // -90 - 90 int as_asin( double as ) { double nearest_diff = 2.0; int nearest_index; for( int i = -90; i <=90; i++ ){ int index = i; if( index < 0 ) index += 360; if( fabs(SinTable[index]-as) < nearest_diff ){ nearest_diff = fabs(SinTable[index]-as); nearest_index = i; } } return nearest_index; } // 0 - 180 int as_acos( double ac ) { double nearest_diff = 2.0; int nearest_index; for( int i = 0; i <= 180; i++ ){ if( fabs(CosTable[i]-ac) < nearest_diff ){ nearest_diff = fabs(CosTable[i]-ac); nearest_index = i; } } return nearest_index; } */