Speccy - наш выбор!

Speccy - наш выбор! (http://zx-pk.ru/index.php)
-   Программирование (http://zx-pk.ru/forumdisplay.php?f=14)
-   -   Быстрое вращение в 3Д (http://zx-pk.ru/showthread.php?t=10209)

TmK 15th May 2009 13:36

Быстрое вращение в 3Д
 
Пытался найти оптимальный способ поворота точек в пространстве, несколько раз почитал статью из ZX Power #3,#4 (можно по ссылке http://zxdn.narod.ru/coding/zpw3gf3d.txt), но так до конца и не въехал.

внимание вопрос:
Может кто попроще объяснить алгоритм?

Vitamin 15th May 2009 17:19

В смысле просто алгоритм поворота точки вокруг другой на определенный градус или именно конкретно оптимизированный?

TmK 15th May 2009 17:53

Интересует алгоритм работы
http://zxdn.narod.ru/coding/zpw3gf3d.txt

Т.е. что хранится в таблица, какие таблицы, когда какие вычисления и т.п.

Естественно интересует конкретно оптимизированный вокруг начала координат)

Higgins 17th May 2009 12:14

В этих исходниках и идеях есть только расчет экранных координат по известным координатам ортов. Вращения ортов там нет.

Судя по тому, сколько радости доставило автору статьи его открытие, еще больше его удивит, что матрица преобразования собственно и составляется из координат ортов, что при раскрытии и дает те же формулы для экранных координат.

В этом смысле смущают, во-первых, сравнение формул для вычисления экранных координат с вращением ортов (две формулы с синусами и косинусами в начале статьи) с формулами для расчета того же по уже повернутым ортам и, во-вторых, противопоставление умножения в этих формулах ("каким бы быстрым оно ни было") тому же умножению в таблицах.

Далее, смущают упоминания ELITE. Опять же, во-первых, в ELITE считается несколько объектов, каждый со своими углами поворота, что по предложенному методу будет означать вычисление таблицы умножения для каждого объекта. Во-вторых, в ELITE дапазоны значений координат объектов куда как шире 64 делений и используются "настоящие" 8- и 16-разрядные умножения. В-третьих, для сравнения, в ELITE умножение считается по таблицам квадратов, что с учетом необходимости генерирования таблиц умножения по методу автора статьи, вряд ли медленнее.

TmK 18th May 2009 11:10

Хорошо, тогда вопрос номер 2:
Кто нито занимался оптимизацией поворота только по двум осям Ох, Оу (в 99% случаев с эффектами заглаза) на основе таблиц.
Самый простой вариант конечно допустим поворот по Ох берем из таблицы, остальное честно считаем.
Какие нито сферические или свои системы координат ктонито использовал (Пусть даже для нечестного с математической точки зрения вращения)?

Higgins 18th May 2009 11:52

Quote:

Originally Posted by TmK (Post 200380)
Кто нито занимался оптимизацией поворота только по двум осям Ох, Оу (в 99% случаев с эффектами заглаза) на основе таблиц.
Самый простой вариант конечно допустим поворот по Ох берем из таблицы, остальное честно считаем.
Какие нито сферические или свои системы координат ктонито использовал (Пусть даже для нечестного с математической точки зрения вращения)?

Если среди Ox и Oy нет оси, которая перпендикулярна экрану, то точки будут вращаться по окружности, проекция которой, в общем случае, будет эллипсом, оси которого будут горизонтальным и вертикальным отрезками, т.е. эллипс будет без наклона -- ровно так, как его только и можно нарисовать быстро. Вращение вокруг горизонтальной оси будет изменять отношение малой оси эллипса к большой: a = b * sin(alpha), где alpha -- угол повотора. Вращение вокруг вертикальной оси будет перемещать точку по дуге получившегося эллипса. Имея представление об алгоритме построения эллписов в растре, это можно сделать быстро даже без таблиц.

key-jee 18th May 2009 12:14

Вот почитай: Поворот 3D вектора за шесть умножений, может поможет))

TmK 18th May 2009 14:17

Quote:

Originally Posted by Higgins (Post 200385)
Если среди Ox и Oy нет оси, которая перпендикулярна экрану, то точки будут вращаться по окружности, проекция которой, в общем случае, будет эллипсом, оси которого будут горизонтальным и вертикальным отрезками, т.е. эллипс будет без наклона -- ровно так, как его только и можно нарисовать быстро. Вращение вокруг горизонтальной оси будет изменять отношение малой оси эллипса к большой: a = b * sin(alpha), где alpha -- угол повотора. Вращение вокруг вертикальной оси будет перемещать точку по дуге получившегося эллипса. Имея представление об алгоритме построения эллписов в растре, это можно сделать быстро даже без таблиц.

Прорабатывал приблизительно такую идею, брал в качестве координат Z, угол Ox, угол Oy. Сломал голову как предыдущий поворот отражается на следующем, ответ эллипс спас от взрыва мозга :)
Подумаю на досуге, хотя уже сделал тупо на основе таблиц coord*sin(alpha), coord*cos(alpha) и таблицы проецирования,
без оптимизации порядка 215 тактов что вполне приемлемо (предыдущий вариант был 110, но пока не знаю как учет эллипса скажется)

newart 18th May 2009 14:53

Главное как решишь вопрос поделись сорцом, уверен пригодится не только мне.
Сам в 3D вообще не шарю, а тут еще оптимизация...

Добавлено через 1 минуту
Странно что CJ молчит. Не все же у них анимация? ;)

TmK 18th May 2009 16:08

Ну код для ротатора на основе таблиц произведений координат на sin/cos углов я думаю не сложно написать.
Вот например: :)

PHP Code:

//----------------------------------------
// 3D 2-Axis table rotator
//----------------------------------------

Максимально возможная длина по осям в одну сторону 15
; (т.еобщая длина оси в обе стороны 31что
в принципе вполне достаточно для чанковых эффектов,
но если нужно например для диапазона в 256 т.едля
точекто можно соответственным образом подкорректировать
таблицу проекцийсчитая ее умножая координаты на 4)

Вычисление таблицы проекций здесь не приводится
Считать ее можно так:
PX X0 + (X*CamDist)/(CamDist+Z));
PY Y0 + (Y*CamDist)/(CamDist+Z));
Для диапазона координат -XYZMAX..0..+XYZMAX

или для диапазона -127..0..+127
PX X0 + (4*X*CamDist)/(CamDist+Z*4));
PY Y0 + (4*Y*CamDist)/(CamDist+Z*4));

где X0,Y0 координаты центра экрана
CamDist расстояние до камеры (подбираем на глаз)

Диапазон изменения угла вращения 0..127
Поворот осуществляется вокруг осей Ox,Oy
по адресу Ay угол вращения вокруг Oy
по адресу Ax угол вращения вокруг Ox

//----------------------------------------
// Переменные и константы
//----------------------------------------
XYZMAX    EQU    15        максимальная длина по осям (в одну сторону)
COR_PZ    EQU    #E0+XYZMAX    ; коэффициент для Z 
COR_Z    EQU    #C0+XYZMAX
COR_PX    EQU    XYZMAX
COR_PY    EQU    
#20+XYZMAX

Начальные координаты точек хранятся в формате
X=X+COR_Z
Y=Y+COR_Z
Z=Z+COR_Z
; (т.ес прибавленным смещением до начала таблиц)

//----------------------------------------
// Формулы вращения
//----------------------------------------

;    OX:
;    
=y*cos(Ay) - z*sin(Ay)
;    
=y*sin(Ay) + z*cos(Ay)

;    
OY:
;    
=x*cos(Ax) - z*sin(Ax)
;    
=x*sin(Ax) + z*cos(Ax)

//----------------------------------------
// Формат хранения таблиц:
//----------------------------------------

Таблица произведений:

;        
#C000           #C080
;        +--------------+--------------+
;   
CoordCoord*cos(A) | Coord*sin(A) |
;        +--------------+--------------+
;        
Alpha          Alpha

Таблица проекций

;     #E000  #E020
;     +------+------+
;    
Z|  PX  |  PY  |
;     +------+------+
;      
X      Y

вообще говоря можно таблицу проекций
совместить с таблицей произведений,
уменьшив при этом диапазон угла
вращений до 0..95как показано ниже,
но приведенные тут значения соответствуют
верхним таблицам

;     #C000          #C060 #C080         #C0E0
;     +--------------+-----+-------------+-----+
;   
CoordCoord*cos(A) | PX  |Coord*sin(A) | PY  |Z
;     +--------------+-----+-------------+-----+
;      
Alpha          X     Alpha         Y


//----------------------------------------
// Создание таблицы произведений:
//----------------------------------------
Изначально имеем таблицу cosA,sinA со значениями*256 (т.емакс знач =1 в старшем байте)
Можно написать генерилкуа можно расчитать на бейсике/паскале

; var
;   
alphainteger;
;   
sc_tbl: array [0..255of word;
; for 
alpha:=0 to 127 do
;   
begin
;   sc_tbl[alpha]:=trunc(256*Cos(alpha*Pi/64));
;   
sc_tbl[alpha+128]:=trunc(256*Sin(alpha*Pi/64));
;   
end;

далее считаем на асме

SC_TBL    INCBIN 
"SC_TBL"        Сгенерированная таблица [512 байт]
TMP_SC    EQU    #????        ; временная таблица, изначально содержит нули [512 байт]

CALC_TBL_PROIZV
    
таблицы считаем накопительным сложением

    
//--- нулевой ряд
    
LD    HL,#C000+XYZMAX*256
    
LD    D,H
    LD    E
,L
    INC    E
    LD    
(HL),0
    LD    BC
,255
    LDIR
    
//--- положительный ряд
    
EXX
    LD    HL
,#C000+256+XYZMAX*256
    
LD    C,XYZMAX
SCC1    EXX
    LD    IX
,TMP_SC
    LD    HL
,SC_TBL
    EXX
    LD    B
,0
SCC0    EXX
    LD    E
,(IX)
    
INC    IX
    LD    D
,(IX)
    
INC    IX
    LD    C
,(HL)
    
INC    HL
    LD    B
,(HL)
    
INC    HL
    EX    DE
,HL
    ADD    HL
,BC
    EX    DE
,HL
    LD    
(IX-2),E
    LD    
(IX-1),D
    LD    A
,D
    EXX
    LD    
(HL),A
    INC    HL
    DEC    B
    JP    NZ
,SCC0
    DEC    C
    JP    NZ
,SCC1
    
//--- отрицательный ряд
    
LD    HL,#C000+256+XYZMAX*256
    
LD    DE,#C000-256+XYZMAX*256
    
LD    C,XYZMAX
SSC3    LD    B
,0
    PUSH    DE
SSC2    LD    A
,(HL)
    
INC    HL
    NEG
    LD    
(DE),A
    INC    DE
    DJNZ    SSC2
    POP    DE
    PUSH    HL
    LD    HL
,0-256
    ADD    HL
,DE
    EX    DE
,HL
    POP    HL
    DEC    C
    JP    NZ
,SSC3
    
//---
    
RET

//----------------------------------------
// Вращение и проецирование:
//----------------------------------------
;    inD-y E-x С-z
;    outD-py,E-px,A-z    спроецированные координаты
//----
ROT3D    //--- вращение по оси OY:
    
LD    L,0        ;7
Ay    EQU    
$-1
    LD    H
,E        ;4    (HL)=X*cosA
    LD    A
,(HL)        ;7    A=X*cosA
    LD    H
,C        ;4
    SET    7
,L        ;8    (HL)=Z*sinA
    SUB    
(HL)        ;7    A=X*cosA-Z*sinA
    ADD    A
,COR_PX    ;7
    LD    B
,A        ;4
    LD    H
,E        ;4
    LD    A
,(HL)        ;7
    LD    H
,C        ;4
    RES    7
,L        ;8
    ADD    A
,(HL)        ;7
    ADD    A
,COR_Z        ;7
    LD    C
,A        ;// 49+24+16=89
    //--- вращение по оси OX:
    
LD    L,0        ;7
Ax    EQU    
$-1
    LD    H
,D        ;4
    LD    A
,(HL)        ;7
    LD    H
,C        ;4
    SET    7
,L        ;8
    SUB    
(HL)        ;7
    ADD    A
,COR_PY    ;7
    LD    E
,A        ;4
    LD    H
,D        ;4
    LD    A
,(HL)        ;7
    LD    H
,C        ;4
    RES    7
,L        ;8
    ADD    A
,(HL)        ;7
    ADD    A
,COR_PZ    ;// 49+24+16=89
    //--- проецирование
    
LD    H,A        ;4
    LD    L
,E        ;4
    LD    D
,(HL)        ;7
    LD    L
,C        ;4
    LD    E
,(HL)        ;7
    SUB    COR_PZ
-XYZMAX    ;// 12+21=33    нормализация Z в диапазоне 0..XYZMAX*2+1
    //---
    
RET 



All times are GMT +4. The time now is 21:01.

Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.