Вы можете полностью избежать деления (и мода), если вы представляете свои углы в чем-то, что называется «BAMS», что означает «Система измерения двоичных углов». Идея состоит в том, что если вы храните ваши углы в N-битном целом числе, вы используете весь диапазон этого целого числа для представления угла. Таким образом, нет необходимости беспокоиться о переполнении после 360, потому что естественные свойства modulo-2 ^ N вашего представления позаботятся об этом за вас.
Например, допустим, вы используете 8 бит. Это разрезает ваш круг на 256 возможных ориентаций. (Вы можете выбрать больше битов, но для примера удобно 8). Пусть 0x00 означает 0 градусов, 0x40 означает 90 градусов, 0x80 - 180 градусов, а 0xC0 - 270 градусов. Не беспокойтесь о знаке, опять же, BAMS является естественным для углов. Если вы интерпретируете 0xC0 как «без знака» и масштабируете до 360/256 градусов на счет, ваш угол равен (+192) (360/256) = +270; но если вы интерпретируете 0xC0 как «со знаком», ваш угол равен (-64) (360/256) = -90. Обратите внимание, что -90 и +270 означают одно и то же в угловых единицах.
Если вы хотите применить функции триггера к углам BAMS, вы можете предварительно вычислить таблицы. Есть хитрости, чтобы уменьшить размеры таблиц, но вы можете видеть, что таблицы не такие большие. Для хранения всей таблицы значений синуса и косинуса с двойной точностью для 8-разрядных BAMS не требуется более 4 КБ памяти, что является курятиной в современных условиях.
Поскольку вы упомянули об использовании этого в игре, вы, вероятно, могли бы избежать использования 8-битных или 10-битных представлений. Каждый раз, когда вы добавляете или вычитаете углы, вы можете преобразовать результат в N битов, используя логическую операцию И, например, угол & = 0x00FF для 8 битов.
ЗАБЫЛ ЛУЧШУЮ ЧАСТЬ (правка)
Проблема поворота вправо против поворота влево легко решается в системе BAMS. Просто возьмите разницу и сохраните только N значащих битов. Интерпретация MSB как знакового бита указывает, в какую сторону вам следует повернуть. Если разница отрицательна, поверните противоположный путь с помощью abs () разницы.
Эта уродливая маленькая программа на C демонстрирует. Попробуйте сначала ввести его как 20 10 и 20 30. Затем попробуйте обмануть его, обернув вокруг нулевой точки. Дайте ему 20 -10, он повернет налево. Дайте ему 20 350, он все еще поворачивает налево. Обратите внимание, что поскольку он выполнен в 8 битах, то 181 неотличим от 180, поэтому не удивляйтесь, если вы подадите ему 20 201, и он поворачивается направо, а не налево - в разрешении, полученном с помощью восьми бит, поверните налево и поверните вправо этот случай одинаков. Положите 20 205, и он пойдет по более короткому пути.
#include <stdio.h>
#include <math.h>
#define TOBAMS(x) (((x)/360.0) * 256)
#define TODEGS(b) (((b)/256.0) * 360)
int main(void)
{
double a1, a2; // "real" angles
int b1, b2, b3; // BAMS angles
// get some input
printf("Start Angle ? ");
scanf("%lf", &a1);
printf("Goal Angle ? ");
scanf("%lf", &a2);
b1 = TOBAMS(a1);
b2 = TOBAMS(a2);
// difference increases with increasing goal angle
// difference decreases with increasing start angle
b3 = b2 - b1;
b3 &= 0xff;
printf("Start at %7.2lf deg and go to %7.2lf deg\n", a1, a2);
printf("BAMS are 0x%02X and 0x%02X\n", b1, b2);
printf("BAMS diff is 0x%02X\n", b3);
// check what would be the 'sign bit' of the difference
// negative (msb set) means turn one way, positive the other
if( b3 & 0x80 )
{
// difference is negative; negate to recover the
// DISTANCE to move, since the negative-ness just
// indicates direction.
// cheap 2's complement on an N-bit value:
// invert, increment, trim
b3 ^= -1; // XOR -1 inverts all the bits
b3 += 1; // "add 1 to x" :P
b3 &= 0xFF; // retain only N bits
// difference is already positive, can just use it
printf("Turn left %lf degrees\n", TODEGS(b3));
printf("Turn left %d counts\n", b3);
}
else
{
printf("Turn right %lf degrees\n", TODEGS(b3));
printf("Turn right %d counts\n", b3);
}
return 0;
}