DonNews #10
21 января 2000 |
|
------------------------------------------ Disabler/DPL Полярные координаты (Всё, что Вы ещё не знаете, или боялись знать!) l.Введение Для начала, сообщу вам, что если вы продвинутый кодер, то, возможно, всё нижеизложенное покажеться примитивным и бессмысленным, но эта статья расчитанна в первую очередь на новичков в демостроении, имеющих некоторые знания o геометрии и ассемблере. Итак, что такое полярные координаты? Это один из способов представления плоскости. Для простоты будем рассматривать двумерную плоскость. Из геометрии вы (надеюсь) знаете, что точка, в двумерном пространстве имеет две координаты - X и Y, которые являются смещением от начала координат. Но это не всегда. Так точка представляется только в декартoвoй системе координат. Однако существует ещё, как минимум одна система координат - пoлярная.B полярной системе координат точка задаётся не двумя координатами, а длинной вектора на котором находится точка (Q) и углом поворота относительно оси OX (Р). И вот тут назревает вопрос: А на..я это надо? Дело вот в чём: например вам надо повернуть точку A с координатами X,Y на угол равный L. При использовании декартoвoй системы координат вы вычисляете: X' = X * cos L - Y * sin L Y' = X * sin L + Y * cos L где X` и Y` - новые координаты, но с точки зрения программирования этот фрагмент можно оптимизировать: SL = sin L CL = cos L X' = X * CL - Y * SL Y' = X * SL + Y * CL здесь мы экономим время вычисления на однократном вычислении синуса и косинуса, которые можно вычислять даже на обычном калькуляторе (Маде ин Жапан) путём двойного умножения, но это тема другой статьи. Да, чуть не забыл, ещё можно вычислять через "пoлинoм Чебышева" или как бесконечный ряд, но, как говориться, в другой раз. Итак, вернёмся к нашему примеру. B полярной системе координат теже действия можно осуществить, следующим образом: Q' = Q P' = P + L Ну, как, проще? А это только начало! Например, имеем квадрат (четыре точки) с центром в начале координат и нам надо увеличить его на какой-либо коэффициент М и повернуть на угол L. B декартoвoй системе координат: SL = sin L CL = cos L Xv = X + M; временные преременные Yv = X + M X' = Xv * CL - Yv * SL Y' = Xv * SL + Yv * CL Чувствуете масштаб вычислений? А теперь берём пoлярныю систему и получаем: Q' = Q + M P' = P + L Назревает oчередний вопрос: Если всё так просто, то почему все не пользуются полярной системой координат? А дело в том, что многие пользуются, но не знают, как это называется, а так-же то, что большенство сложных объектов проще представлять в декартoвoй системе и выводить на экран тоже проще в декартoвoй системе. Но, как говориться, не всё так сложно, как может показаться, особенно из ассм`а. Я не буду долго распинаться и грузить вас и себя тоже нудным выводом формул, а сразу приведу готовые. Чтобы поставить точку по полярным кooрдинарам есть формула: X = Q * cos P Y = Q * sin P А если надо переверсти наоборот декартoвые координаты в полярные - поможет формула: _______ P=/X*X+Y*Y Q=arctg (Y/X) Я искренне надеюсь, что вы НИКОГДА не будете пользоваться этими формулами, потому что использование их из ассм`а весьма затруднительно, особенно для перевода из декартовых в полярные координаты. 2.Использование в ассм'е Для начала нам (не нам, а вам!) нужно уметь "зафoрмить" таблицу синуса, которая по совместительству будет таблицей косинуса. И тут нам поможет всеми "любимый" Basic`48. Входим и набираем следующее: l0 Let adr=32768 20 Let atplit=64 30 For x=-Pi то Pi Step Pi/l28 40 Let sinx=l28 + atplit * Sin x S0 Роке adr,sinx 60 Let adr=adr + l 70 Next x 80 Rand Usr lSбl9: Ret: Save "sin" Code 32768,2S6 Данная прога зафoрмит и coxpohut на диске файлик "sin", внутри которого лежит один период синуса с амплитудой от -64 до +64 и поднятый относительно оси OX на 128, т. е. реальные значения будут от 64 до 192. Если вы не поняли: зачем это надо? Поясняю - в ассм`е работать со знаковыми числами неоправданно сложно, да нам это и не надо. B дальнейшем нам потребуется таблица таблиц синуса, т. е. 64 таблицы синуса с амплитудой от -1 до +1,..., от -64 до +64. Размер каждой таблицы - 256 байт. Это нужно для того чтобы при загрузке по "ровному" шестнадцатиричнoму адресу (адрес у которого младший байт равен нулю, например: #6000, #7800 и т. д.) каждая пoдтаблица, так же, разпoлoгалась с ровного адреса. Итак, есть таблица, есть ассм. Остаётся всё это закодить :). Грузим XAS и набираем нечто для вывода и поворота на заданный угол четырёх точек: ;----------------------------------------- ; Поворот на угол "angle" при переменной P ; равной константе (64) pointz equ 4; Количество точек org #6000 sinus lcode "sin"; Грузим таблицу ent; Вот и начало! ld hl,#4000; Очищаем экран ld d,h ld e,l inc e ld (hl),l ld ьс,6l44 ldir ld (hl),7l ld ьс,767 ldir call view; Выводим точки sleep хог a; Ждём нажатия любой кнопки in a,#fe; после чего вываливаемся cpl; отсюда! and 3l jr z,sleep ret; Выход! view ld a,(angle) ld с,a ld b,pointz ; c = угол поворота ; b = количество точек ld hl,table viewl push ьс,hl ld a,(hl) add a,с ld h,sinus&h; берём старший байт ; адреса таблицы ld l,a ld e,(hl) ; выбераем первую координату add a,64 ; увеличиваем "a" на 64, что равнозначно ; переходу от синуса к косинусу, т.е. ; cos x = sin (x + pi/2), а в данном ; случае pi/2 = 64, или четверть таблицы ; синуса ld l,a ld a,(hl) ld с,a ld a,e ; выбераем вторую координату call pixel; ставим точку pop hl,ьс inc hl ; переходим к следующей точке djnz viewl ret ; процедура точки, тормозная но маленькая pixel call 8880 add a,a add a,a add a,a ld b,a ld a,#fe sub b ld (pixell+l),a pixell set 0,(hl) ret angle db 0; угол поворота (0..255) table db 0,64,l28,l92 ; таблица углов "Q" ; ANGLEassm = (256 * ANGLEreal) / 360 А теперь прога, которая пoварачивает на заданный угол и одновременно увеличивает "квадрат". Файл "sin2" - набор таблиц синуса (см. выше). ;----------------------------------------- ; Поворот на угол "angle" и ; масштабирование на заданный коэффициент pointz equ 4; Количество точек org #6000 sinus lcode "sin2"; Грузим таблицу ent; Вот и начало! ld hl,#4000; Очищаем экран ld d,h ld e,l inc e ld (hl),l ld ьс,6l44 ldir ld (hl),7l ld ьс,767 ldir call view; Выводим точки sleep хог a; Ждём нажатия любой кнопки in a,#fe; после чего вываливаемся cpl; отсюда! and 3l jr z,sleep ret; Выход! view ld a,(angle) ld с,a ld b,pointz ; c = угол поворота ; b = количество точек ld hl,table viewl push ьс,hl ld a,(hl) add a,с ld с,a inc hl ld a,(tagnif) add a,(hl) add a,sinus&h; берём старший байт ld h,a; адреса таблицы ld l,с ld e,(hl) ; выбераем первую координату ld a,с add a,64 ; увеличиваем "a" на 64, что равнозначно ; переходу от синуса к косинусу, т.е. ; cos x = sin (x + pi/2), а в данном ; случае pi/2 = 64, или четверть таблицы ; синуса ld l,a ld a,(hl) ld с,a ld a,e ; выбераем вторую координату call pixel; ставим точку pop hl,ьс inc hl inc hl ; переходим к следующей точке djnz viewl ret ; процедура точки, тормозная но маленькая pixel call 8880 add a,a add a,a add a,a ld b,a ld a,#fe sub b ld (pixell+l),a pixell set 0,(hl) ret angle db 0; угол поворота (0..255) tagnif db 0; масштаб (1..64) table db 0,l0,64,l0,l28,l0,l92,l0 ; таблица углов "Q", и длинн векторов "P" Приведённые примеры выводят на экран четыре точки и ждут нажатия любой клавиши для выхода. Однако, если ожидание нажатия клавиши заменить на нижеследующее, то получиться эффект плавного вращения. ... loop halt call cls_pix call view ld hl,angle inc (hl) хог a in a,#fe cpl and 3l jr z,loop ... Где "cls_pix" - процедура стирания точек Вот, пожалуй, и всё, что я мог поведать вам o такой страшной вещи, как пoлярная система координат. Если возникли вопросы пишите на адрес редакции, ответим всем! B следующем номере я поведаю вам o алгоритмах быстрого вычисления функций sin (x), cos(x), а так-же o алгоритмах быстрого умножения, деления и возведения в квадрат.
Other articles:
|
|
|
|
|
|
|
|
|
|
|
|
|
Similar articles:
В этот день... 21 November