旋转缓存的设计
关于旋转Lite2D之前选用了矩阵的转换 发现自己写出来的效率还不如普通的计算算法加上缓存
由于sin cos 的计算很费时间,所以设计了一个缓存,程序启动后就 计算0-90度的结果,精度为0.000001 ,这样 计算就快多了
一下是Lite2D的实现
float Math::sin(const float& angle)
{
static const int scale = 100000;
static const int maxAngle = 360 * scale;
static const int arraySize = maxAngle / 4;
static float _sin[arraySize] = { 0 };
// init sin
if (!_sin[1])
{
if (auto prf = fopen("sin.dat", "rb"))
{
fread(&_sin, sizeof(float), arraySize, prf);
fclose(prf);
}
else
{
const auto step = 3.1415926535898 / (arraySize * 2);
auto radian = .0;
for (int i = 0; i < arraySize; ++i, radian += step)
{
_sin[i] = static_cast<float>(std::sin(radian));
}
auto t = std::thread([=]
{
// write into file
if (FILE *pwf = fopen("sin.dat", "wb"))
{
fwrite(_sin, sizeof(float), arraySize, pwf);
fclose(pwf);
}
});
t.detach();
}
}
auto realAngle = angle*scale;
if (realAngle >= maxAngle || realAngle < 0)
{
realAngle = int(realAngle + (realAngle >= 0 ? 0.5 : -0.5)) % maxAngle;
if (realAngle < 0)
realAngle += 360;
}
int index = int(realAngle);
switch (index / arraySize)
{
case 0:
return _sin[index];
case 1:
if (index == arraySize)
return 1;
return _sin[2 * arraySize - index];
case 2:
return -_sin[index - 2 * arraySize];
case 3:
if (index == 3 * arraySize)
return -1;
return -_sin[maxAngle - index];
}
return 0;
}
float Math::cos(const float& angle)
{
return sin(angle + 90);
}
其实没必要写入文件缓存,因为I/O速度慢多了