Echo
#01
31 октября 1996 |
|
Ассемблер - Изображение трехмерных объектов. Быстрый вывод точки AT X,Y. Процедура умножения.
┌═══ ---------------------- ═══┐ ├ Изображение трехмерных ┤ ├ объектов. ┤ └═══ ---------------------- ═══┘ Все видели словацкую демку ECHOLOGY. Не правда ли круто? (речь идет о ее 3D PART). Сейчас я попытаюсь рассказать как это сделать. 1) нужно написать быстрый вывод точки, т.к. он больше всего вли- яет на итоговую скорость работы всей программы; 2) затем написать быстрый вывод всего отрезка (а точнее вектора) скорость работы этой процедуры на втором месте по важности; 3) делай, что хочешь... (с приколами у меня напряженка!) Приведу несколько цифр, к которым надо стремиться при на- писании вывода точки и отрезка: Точка - примерно 100/110Т Точка в отрезке 200Т Таких результатов добился я, но это не говорит о том, что нельзя сделать быстрее... Теперь надо сделать, чтобы по- следовательность координат сое- динялась отрезками (этим ты до- бьешься устойчивого положения объекта на экране, такого устой- чивого, что даже последователь- ность команд di:halt не сотрет с экрана плоды твоего труда). В конце концов вам все-таки надоест устойчивое положение мо- нитора... тьфу!... экрана и на- до бы его повертеть (или покру- тить). А! Я забыл напомнить о том,что в 3DGRAPH (ну, это где три оси: X,Y и Z) каждая точка задается тремя координатами. И теперь я вас всех поражу, сообщив о том, что при выводе на экран 3D-точки надо использовать лишь две координаты: Х и Y (не правда ли, вы поражены ?). Ну ладно, вернемся к вопросу о поворотах (и наворотах) фигуры. Приведу несколько формул, ко- торыми пользуюсь я (и наверное кто-нибудь еще): а) поворот на угол (а) вокруг оси X: X'=X; Y'=COS(а)*Y-SIN(а)*Z; Z'=SIN(а)*Y+COS(а)*Z; б) поворот на угол (а) вокруг оси Y: X'=SIN(а)*Z+COS(а)*X; Y'=Y; Z'=COS(а)*Z-SIN(а)*X; в) поворот на угол (а) вокруг оси Z: X'=COS(а)*X-SIN(а)*Y; Y'=SIN(а)*X+COS(а)*Y; Z'=Z; Надеюсь, что вы не будете пе- ред выводом фигуры рассчитывать ее положение, а заранее создади- те таблицу (если объект рисуется отрезками, то в таблице лучше хранить не координаты вершин, а вектора, так будет быстрее ...). Как хранить числа или вектора в таблице ? Лично я пользуюсь таким мето- дом: числа по модулю вряд ли бу- дут больше чем #7F, значит 7-ой бит будет знаковым: 1-число от- рицательное, 0-положительное. Для вектора мы должны знать смещения и их направления. Т.е. вектор будет занимать в памяти 2 байта (1-ый байт смещение и нап- равление по оси X, 2-ой - по Y). К вопросу о погрешностях. Когда я писал свой трехмерный эффект, то чуть не получил ин- фаркт, увидев как мой прелестный кубик за 2 секунды вращения пре- вратился в неправильный шести- гранник (тоже неплохой эффект !) Оказалось, что все дело в по- грешности, которая была при рас- четах. Могу дать пару советов: 1) все вычисления проводите в калькуляторе ПЗУ (или в своем); 2) промежуточные результаты храните в 5-ти байтовом формате; 3) округление проводить только для тех чисел, которые заносятся в таблицу, а их вещественные значения оставлять для последую- щих расчетов; У меня скорость создания таб- лицы для кубика на 200 его поло- жений с использованием ПЗУ, при- мерно 40 сек. Я примерно знаю, как сделать, чтобы фигура не только вращалась но и увеличивалась и уменьшалась по ходу вращения, но сам еще не сделал (лень). P.S. Если все вышенаписанное умело профильтровать, то из него можно вытянуть некоторую полезную инфор- мацию. P.P.S.Почти все, что я расска- зал о 3D-графике вы уви- дите в нашем DISTURBANCE Demo, которое вскоре дол- жно выйти (а может и не выйти). DISTORTER (Демкович Иван) ADIA SOFT, Брест, 27.8.96 224017, г.Брест Московская, 267/3-47 Звоните (0162)411655 +------------------------------+ Комментарий VfNG/NHG: Вот это ADIA поприкалывались. Статья в целом интересная, кое-что действительно вытянуть можно. Приведу в дополнение несколько полезных вещей: 1) быстрый вывод точки AT X,Y: LD H,D ;4 LD E,(HL) ;7 INC H ;4 LD A,(HL) ;7 LD L,B ;4 INC H ;4 OR (HL) ;7 LD C,A ;4 INC H ;4 LD B,(HL) ;7 LD A,(BC) ;7 OR E ;4 LD (BC),A ;7 Всего 70 тактов. Что-где находиться на входе- не скажу, чтобы интереснее было. Никто не сказал, что именно этой процедурой надо пользоваться при выводе. Это так, для тренировки. 2) Классная процедурка умножения (очень похожая торчит в ECHOLOGY): H-число 1; E-число 2; L,D=0 ; ADD HL,HL JR NC,L1 ADD HL,DE L1 ADD HL,HL JR NC,L2 ADD HL,DE L2 ADD HL,HL JR NC,L3 ADD HL,DE L3 ADD HL,HL JR NC,L4 ADD HL,DE L4 ADD HL,HL JR NC,L5 ADD HL,DE L5 ADD HL,HL JR NC,L6 ADD HL,DE L6 ADD HL,HL JR NC,L7 ADD HL,DE L7 ADD HL,HL JR NC,L8 ADD HL,DE L8 Выход - в HL результат. Здесь мудро применено разло- жение чисел на двоичные множите- ли. Очень советую разобраться в этой процедурке! 3) Числа из промежутка [0;1) ре- комендую умножать на 256 и в та- ком формате хранить. Если вам нужно, например, умножить синус числа на какую-либо хрень, то предидущей процедуркой это дела- ется так: H-синус*256 (если он равен 1, и вы еще собираетесь его на что-то умножать, то...), E-эта самая хрень, на выходе: в H целая, в L дробная части резу- льтата. 4) Углы гораздо приятнее считать не в градусах или радианах, а в 1/256 полного поворота. 5) Использовать калькулятор из ПЗУ-варварство. Для промежуто- чных исследований еще туда-сюда, но не более. Работа с собствен- ными, умело написанными процеду- рами дает ускорение в 10-20 раз по сравнению с ПЗУ. Погрешности, вообще-то, не так уж и страшны. Вполне хватит точности до 1/256. 6) С увеличением/уменьшением то- же просто: умножаете X и Y на ???/Z (снова сами подумайте!). Все, что я тут понаписывал, ни в коем случае нельзя исполь- зовать по-дубовому напрямую. Вот вам пара идей-намеков: думайте. Нельзя сказать, естественно, что это мои наивысшие достижения (как и всякий нормальный человек своих секретов так просто не вы- дам). Между прочим, у меня в че- ртилочке вывод занимает 22-110 (в среднем 40) тактов... И вооб- ще в чертилке вывод точки должен идти быстрее, чем просто так, от балды. Can do better? +------------------------------+
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября