Assembler - язык неограниченных возможностей


Трансцендентные функции


Многие операции при работе с графикой используют умножение числа на синус (или косинус) некоторого угла, например при повороте: s = sin(n) * v. При использовании арифметики с фиксированной точкой 16:16 это уравнение преобразуется в s = int(sin(n) * 65 536) * v/65 536 (где int — целая часть). Для требовательных ко времени работы участков программ, например для работы с графикой, принято вообще не вычислять значения синусов, а считывать из таблицы, содержащей значения выражения int(sin(n) * 65 535), где n меняется от 0 до 90 градусов с требуемым шагом (редко требуется шаг меньше 0,1 градуса). Затем синус любого угла от 0 до 90 градусов можно вычислить с помощью всего одного умножения и сдвига на 16 бит. Синусы других углов и косинусы вычисляются в соответствии с обычными формулами приведения:

sin(x) = sin(180-x) для 90 < х < 180 sin(x) = -sin(x-180) для 180 < х < 270 sin(x) = -sin(360-x) для 270 < х < 360 cos(x) = sin(90-x)

хотя часто используют таблицу синусов на все 360 градусов, устраняя дополнительные проверки и изменения знаков в критических участках программы.

Таблицы синусов (или косинусов), используемые в программе, можно создать заранее с помощью простой программы на языке высокого уровня в виде текстового файла с псевдокомандами DW и включить в текст программы директивой include. Другой способ, занимающий меньше места в тексте, но чуть больше времени при запуске программы, — однократное вычисление всей таблицы. Таблицу можно вычислять как с помощью команды FPU fsin и потом преобразовывать к желаемому формату, так и сразу в формате с фиксированной запятой. Существует довольно популярный алгоритм, позволяющий вычислить таблицу косинусов (или синусов, с небольшой модификацией), используя рекуррентное выражение

cos(xk) = 2cos(step)cos(xk-1) - cos(xk-2)

где step — шаг, с которым вычисляются косинусы, например 0,1 градуса.

; liss.asm ; строит фигуры Лиссажу, используя арифметику с фиксированной запятой ; и генерацию таблицы косинусов. ; Фигуры Лиссажу - семейство кривых, задаваемых параметрическими выражениями ; x(t) = cos(SCALE_V * t) ; y(t) = sin(SCALE_H * t) ; ; чтобы выбрать новую фигуру, измените параметры SCALE_H и SCALE_V, ; для построения незамкнутых фигур удалите строку add di,5l2 ; в процедуре move_point




Начало  Назад  Вперед