旋转缓存的设计

关于旋转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速度慢多了

你可能感兴趣的:(旋转缓存的设计)