📄 gtrigtable.cpp
字号:
/* Copyright (C) 2006, Mike Gashler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. see http://www.gnu.org/copyleft/lesser.html*/#include "GTrigTable.h"#include <math.h>#include <stdlib.h>#include "GMacros.h"GPrecalculatedTrigTable::GPrecalculatedTrigTable(int nDivisions){ m_nDivisions = nDivisions; m_dDivisionSize = (PI / 2) / nDivisions; m_pTable = new double[nDivisions + 1]; int n; for(n = 0; n < nDivisions; n++) m_pTable[n] = sin(n * (PI / 2) / nDivisions); m_pTable[nDivisions] = 1;}GPrecalculatedTrigTable::~GPrecalculatedTrigTable(){ delete(m_pTable);}double GPrecalculatedTrigTable::Sin(double d){ // Move d to between 0 and 2 * PI if(d >= (2 * PI)) d -= (2 * PI * (int)(d / (2 * PI))); else if(d < 0) d += (2 * PI * ((int)((-d) / (2 * PI)) + 1)); // Move d to between 0 and PI bool bNegate = false; if(d >= PI) { bNegate = true; d -= PI; } // Move d to between 0 and PI / 2 if(d >= (PI / 2)) d = PI - d; // Interpolate the value from the table int nDiv = (int)(d / m_dDivisionSize); if(nDiv >= m_nDivisions) nDiv = m_nDivisions - 1; double dPos = d - (nDiv * (PI / 2) / m_nDivisions); double dVal = dPos * m_pTable[nDiv + 1] + (1 - dPos) * m_pTable[nDiv]; // Return the value if(bNegate) return -dVal; else return dVal;}double GPrecalculatedTrigTable::Cos(double d){ return(Sin((PI / 2) - d));}#ifndef NO_TEST_CODE#ifdef WIN32#include <windows.h>#endif // WIN32void TestGPrecalculatedTrigTableForAccuracy(){ GPrecalculatedTrigTable trig(524288); // Test critical Sine values if(ABS(trig.Sin(0) - sin((double)0)) > .000001) throw "failed"; if(ABS(trig.Sin(PI / 2) - sin(PI / 2)) > .000001) throw "failed"; if(ABS(trig.Sin(PI) - sin(PI)) > .000001) throw "failed"; if(ABS(trig.Sin(2 * PI) - sin(2 * PI)) > .000001) throw "failed"; if(ABS(trig.Sin(-PI / 2) - sin(-PI / 2)) > .000001) throw "failed"; if(ABS(trig.Sin(-PI) - sin(-PI)) > .000001) throw "failed"; if(ABS(trig.Sin(-2 * PI) - sin(-2 * PI)) > .000001) throw "failed"; // Test critical Cosine values if(ABS(trig.Cos(0) - cos((double)0)) > .000001) throw "failed"; if(ABS(trig.Cos(PI / 2) - cos(PI / 2)) > .000001) throw "failed"; if(ABS(trig.Cos(PI) - cos(PI)) > .000001) throw "failed"; if(ABS(trig.Cos(2 * PI) - cos(2 * PI)) > .000001) throw "failed"; if(ABS(trig.Cos(-PI / 2) - cos(-PI / 2)) > .000001) throw "failed"; if(ABS(trig.Cos(-PI) - cos(-PI)) > .000001) throw "failed"; if(ABS(trig.Cos(-2 * PI) - cos(-2 * PI)) > .000001) throw "failed"; // Test random Sine and Cosine values double d; double d1; double d2; int n; for(n = 0; n < 10000; n++) { d = (double)(rand() - (RAND_MAX / 2)) / (((double)rand()) / 1000); d1 = trig.Sin(d); d2 = sin(d); if(ABS(d1 - d2) > .00001) throw "failed"; d1 = trig.Cos(d); d2 = cos(d); if(ABS(d1 - d2) > .00001) throw "failed"; }}void TestGPrecalculatedTrigTableForSpeed(){#ifdef WIN32 GPrecalculatedTrigTable trig(360); // Make sure precalculated table is faster than math functions __int64 nClockBefore; __int64 nClockAfter; __int64 nDiff1; __int64 nDiff2; int n; double d; srand(12345); QueryPerformanceCounter((LARGE_INTEGER*)&nClockBefore); for(n = 0; n < 100000; n++) { d = trig.Sin(rand()); d = trig.Cos(rand()); } QueryPerformanceCounter((LARGE_INTEGER*)&nClockAfter); nDiff1 = nClockAfter - nClockBefore; srand(12345); QueryPerformanceCounter((LARGE_INTEGER*)&nClockBefore); for(n = 0; n < 100000; n++) { d = sin((double)rand()); d = cos((double)rand()); } QueryPerformanceCounter((LARGE_INTEGER*)&nClockAfter); nDiff2 = nClockAfter - nClockBefore; if(nDiff1 > nDiff2) throw "failed";#endif // WIN32}/*static*/ void GPrecalculatedTrigTable::Test(){ TestGPrecalculatedTrigTableForAccuracy();// TestGPrecalculatedTrigTableForSpeed();}#endif // !NO_TEST_CODE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -