====== Целочисленная тригонометрия ====== На PlayStation все вычисления рекомендуется производить в целочисленной арифметике, и синусы/косинусы - не исключение. Самый эффективный способ реализации тригонометрии - таблица синусов. На самой консоли ничего вычислять не нужно, вместо этого функция sin просто обращается к таблице по индексу, полученному из угла. Таблица вычисляется заранее на ПК и сохраняется в виде массива из 16-битных целых. Чем больше таблица, тем выше угловая точность. Пример программы на D, которая генерирует таблицу синусов для 4096 углов (8 KiB) в формате Q3.12: import std.math: sin, PI, round; import std.file: write; enum COUNT = 4096; enum SCALE = 0x1000; void main() { ubyte[] data; data.length = COUNT * 2; foreach (i; 0..COUNT) { double angle = 2.0 * PI * i / COUNT; short value = cast(short)round(sin(angle) * SCALE); data[i * 2 + 0] = cast(ubyte)(value & 0xff); data[i * 2 + 1] = cast(ubyte)(value >> 8); } write("sin4096.bin", data); } Функция чтения на C: short sin(uint angle) { return sinTable[angle & 0xfff]; } Косинус реализуется аналогично, но со сдвигом по фазе: #define HPI 0x400 short cos(uint angle) { return sinTable[(angle + HPI) & 0xfff]; } Число PI в Q3.12 будет равно 0x800. Точность метода достаточна для представления поворотов в 3D-играх. Чем больше угловая скорость, тем менее заметны артефакты дискретности.