#include "FixedMath.h" #include namespace FixedMath { static const double Pi = 3.1415926535897932384626433832795; MathTable::TableData MathTable::Table; MathTable::TableData::TableData(void) { int i; for (i = 0;i < AngleNum;i++) { SinTable[i] = static_cast(Fixed( sin(Pi * i / (AngleNum / 2)) ).GetFixedValue()); } for (i = 0;i < 1 << (2 + SqrtBelowPointPrecision);i++) { SqrtTable[i] = static_cast(Fixed( sqrt(static_cast(i) / (1 << SqrtBelowPointPrecision)) ).GetFixedValue()); } double a45 = (1 << AtanTableBit); for (i = 0;i < (1 << AtanTableBit) + 1;i++) { AtanTable[i] = static_cast(atan(i / a45) * AngleNum / 2 / Pi); } } Fixed Sqrt(Fixed square) { int i = 0; long sq = square.GetFixedValue(); while (sq >= Fixed(256).GetFixedValue()) { i += 4;sq >>= 8; } if (sq >= Fixed(64).GetFixedValue()) { i += 3;sq >>= 6; } if (sq >= Fixed(16).GetFixedValue()) { i += 2;sq >>= 4; } if (sq >= Fixed(4).GetFixedValue()) { i++;sq >>= 2; } return Fixed::FixedValue( MathTable::Table.SqrtTable[sq >> (FixedShift - SqrtBelowPointPrecision)] << i ); } short Atan(long x,long y) { if (x == 0 && y == 0) return 0; long max = 1 << (31 - AtanTableBit); if (x >= max || x < -max || y >= max || y < -max) { //途中でオーバーフローしそうなら x >>= AtanTableBit; y >>= AtanTableBit; } if (y >= 0) if (x >= 0) { if (x > y) return MathTable::Table.AtanTable[(y << AtanTableBit) / x]; else return (AngleNum >> 2) - MathTable::Table.AtanTable[(x << AtanTableBit) / y]; } else { if (y > -x) return (AngleNum >> 2) + MathTable::Table.AtanTable[(-x << AtanTableBit) / y]; else return (AngleNum >> 1) - MathTable::Table.AtanTable[(y << AtanTableBit) / -x]; } else { if (x <= 0) { if (-x > -y) return (AngleNum >> 1) + MathTable::Table.AtanTable[(-y << AtanTableBit) / -x]; else return AngleNum - (AngleNum >> 2) - MathTable::Table.AtanTable[(-x << AtanTableBit) / -y]; } else { if (-y > x) return AngleNum - (AngleNum >> 2) + MathTable::Table.AtanTable[(x << AtanTableBit) / -y]; else return AngleNum - MathTable::Table.AtanTable[(-y << AtanTableBit) / x]; } } } }