Deja Vu #06
30 сентября 1998

CODING - Уроки кодера: Фрактальный папаратник.

SoundTrack: FrEsHeR / PHaNtIm FaMiLy 1998 
__________________________________________


(C) Max/Cyberax Software/BD
__________________________________________


          Фрактальный папоротник
          ----------------------


   Первый  раз я увидел  его на pC - попа-
лась  небольшая  программка на  Q.BASIC'е.
Вскоре  я  сделал  ее аналог на спековском
бейсике, а сейчас предлагаю асмовую реали-
зацию.
   Принцип  построения  довольно  простой.
Имеем следующие рекуррентные формулы:

 XNEW=XOLD*A+YOLD*B+C
 YNEW=XOLD*D+YOLD*E+F


Здесь A,B,C,D,E и F - коэффициенты.


   Насколько я понял, данные  формулы зак-
лючают  в  себе  преобразования  поворота,
масштабирования  и переноса  координат од-
новременно.
   Коэффициентов у нас будет 4  набора  и,
соответствено, 4 варианта формул:

    +-----+-----+-----+-----+-----+-----+
    |  A  |  B  |  C  |  D  |  E  |  F  |
+---+-----+-----+-----+-----+-----+-----+
| 1 |  0  |  0  |  0  |  0  | .16 |  0  |
| 2 | .85 | .4  |  0  |-.04 | .85 | 1.6 |
| 3 | .2  |-.26 |  0  | .23 | .23 | 1.6 |
| 4 |-.15 | .28 |  0  | .26 | .24 | .44 |
+---+-----+-----+-----+-----+-----+-----+


   Для построения  фрактала  нужно  задать
начальные значения координат X и Y.
   Затем  закручиваем  бесконечный цикл. В
цикле для получения последующих X, Y через
предыдущие, применяем одну из 4-х формул с
вероятностью:

 1% (1-я), 85% (2-я), 7% (3-я), 7% (4-я).

(Где-то я читал,  что эти вероятности про-
порциональны площадям листьев папоротника)
   Выбор формул производится просто: берем
(где-нибудь...) RND-число от 0 до 1, затем
смотрим, в какой диапазон попало число.

R = [0.00, 0.01] - 1-й набор коэф-тов
R = (0.01, 0.86] - 2-й
R = (0.86, 0.93] - 3-й
R = (0.93, 1.00] - 4-й


└s      М          Вышеприведенные зна-
З└s      Е          чения коэффициентов
┴sP     С     P    и вероятностей взяты
Х┴sU     Т     U    из pC-программки.
┬sT     О     T
г┬s                 Цикл  можно оборвать
*├sH     Д     H    после  достаточного
▒├sE     Л     E    количества итераций.
8─sR     Я     R    Результатом  работы
┐─sE           E    будет примерно такая
F┼s      С          картинка.
═┼s!     П     !
T╞s      Р          Для реализации всей
█╞s      А          этой ахинеи,  я ис-
b╟s      Й          пользовал fixed point
щ╟s      Т          calculations  8.8, с
p╚s      А          учетом знака (8 битов
ў╚s                 до запятой и 8 - пос-
~╔s     л           ле).
╩s     л
М╩s     л
╦s     л

Теперь, собственно, листинг:

        ORG   #6000
        ENT
;Written by Max/CBX/BD
;XAS Assembler v7.447, 15.08.98.


DOT     EQU   #C0;   Килобайтная табличка.
X_SCALE EQU   #1800; Коэф-ты растяжения по
Y_SCALE EQU   #1200; X и по Y.

        DI
        CALL  INIT
        LD    IX,0
FRACTAL LD    HL,CONST1
        LD    DE,12
        LD    A,R
        ADD   A,#AA
        RLCA
RN      XOR   0
        XOR   (IX)
        INC   IX
        LD    (RN+1),A; A - RND-число.
        CP    3
        JR    C,OK
        ADD   HL,DE
        CP    220
        JR    C,OK
        ADD   HL,DE
        CP    238
        JR    C,OK
        ADD   HL,DE
OK      LD    A,HX; Выбрали нужный набор
        AND   #3F;  коэффициентов.
        LD    HX,A
        PUSH  HL
        LD    DE,(X)
        CALL  MUL_NM1
        LD    (TMP1+1),HL
        POP   HL
        INC   L
        INC   L
        PUSH  HL
        LD    DE,(Y)
        CALL  MUL_NM1
TMP1    LD    DE,0
        ADD   HL,DE
        EX    DE,HL
        POP   HL
        INC   L
        INC   L
        LD    C,(HL)
        INC   L
        LD    B,(HL)
        INC   L
        EX    DE,HL
        ADD   HL,BC
        PUSH  HL
        EX    DE,HL
        PUSH  HL
;XNEW вычислили.
        LD    DE,(X)
        CALL  MUL_NM1
        LD    (TMP2+1),HL
        POP   HL
        INC   L
        INC   L
        PUSH  HL
        LD    DE,(Y)
        CALL  MUL_NM1
TMP2    LD    DE,0
        ADD   HL,DE
        EX    DE,HL
        POP   HL
        INC   L
        INC   L
        LD    C,(HL)
        INC   L
        LD    B,(HL)
        EX    DE,HL
        ADD   HL,BC
        LD    (Y),HL
;YNEW тоже вычислили.
        EX    DE,HL
        LD    BC,Y_SCALE
        CALL  MUL_NM2; Масштабируем Y.
        EX    DE,HL
        LD    HL,#C000
        AND   A
        SBC   HL,DE
        LD    A,H
        EX    AF,AF
        POP   DE
        LD    (X),DE
        LD    BC,X_SCALE
        CALL  MUL_NM2; Масштабируем X.
        LD    DE,#8000
        ADD   HL,DE
        LD    B,H
        EX    AF,AF
        LD    H,DOT;  Ставим точку.
        LD    L,A
        LD    A,(HL)
        INC   H
        LD    D,(HL)
        INC   H
        LD    L,B
        OR    (HL)
        LD    E,A
        INC   H
        LD    A,(DE)
        OR    (HL)
        LD    (DE),A
        LD    A,#7F
        IN    A,(#FE); Опрос SPACE.
        RRCA
        JP    C,FRACTAL
        EI
        RET


MUL_NM1 LD    C,(HL)
        INC   L
        LD    B,(HL)
;Процедура  умножения  двух знаковых чисел
;формата 8.8 (регистры DE и BC):
MUL_NM2 LD    A,D
        AND   A
        JP    P,NONEG1
        CPL
        LD    D,A
        LD    A,E
        CPL
        LD    E,A
        INC   DE
;Чтобы  изменить  знак  числа, его (число)
;нужно инвертировать и увеличить на 1.
        LD    A,B
        AND   A
        JP    P,NONEG2
        CPL
        LD    B,A
        LD    A,C
        CPL
        LD    C,A
        INC   BC
NONEG3  XOR   A
        JP    ML2
NONEG2  LD    A,#FF
        JP    ML2
NONEG1  LD    A,B
        AND   A
        JP    P,NONEG3
        CPL
        LD    B,A
        LD    A,C
        CPL
        LD    C,A
        INC   BC
        LD    A,#FF
;В данный момент DE содержит модуль 1-го
;сомножителя, а BC - второго.
;В аккумуляторе - 0 или FF - знак рез-та.
ML2     LD    HL,0
        !ASSM 16
        RR    B
        RR    C
        JR    NC,$+3
        ADD   HL,DE
        RR    H
        RR    L
        !CONT
        RR    B
        RR    C
;В HLBC сейчас сидит число в формате 16.16
;(результат умножения 8.8 * 8.8).
;Далее, если число должно быть отрицатель-
;ным - меняем его знак.
;После всего этого бесцеремонно отбрасыва-
;ем по байту с начала и с конца и загоняем
;результат в HL.
        RRCA
        JR    NC,NONEG4
        LD    A,C
        CPL
        ADD   A,1
        LD    A,L
        CPL
        LD    H,A
        LD    A,B
        CPL
        LD    L,A
        RET   NC
        INC   HL
        RET
NONEG4  LD    H,L
        LD    L,B
        RET


;Инициализация.

INIT    XOR   A
        OUT   (#FE),A
        LD    HL,#4000
        PUSH  HL
        LD    DE,#4001
        LD    BC,#1800
        LD    (HL),L
        LDIR
        LD    BC,#2FF
        LD    (HL),68
        LDIR
        POP   DE
        LD    H,DOT
        LD    L,E
        LD    B,#C0
MK_ADTB LD    (HL),E
        INC   H
        LD    (HL),D
        DEC   H
        INC   L
        INC   D
        LD    A,D
        AND   7
        JP    NZ,C1
        LD    A,E
        ADD   A,32
        LD    E,A
        JR    C,C1
        LD    A,D
        SUB   8
        LD    D,A
C1      DJNZ  MK_ADTB
CL_LP   LD    (HL),B
        INC   H
        LD    (HL),B
        DEC   H
        INC   L
        JR    NZ,CL_LP
        INC   H
        INC   H
        LD    BC,#801F
MK_B_TB LD    A,L
        RRCA
        RRCA
        RRCA
        AND   C
        LD    (HL),A
        INC   H
        LD    (HL),B
        DEC   H
        RRC   B
        INC   L
        JR    NZ,MK_B_TB
        RET


        ORG   $/256+1*256


;Таблица констант с fixed point.
;Должна располагаться с /256 адреса.
;
;В формат 8.8 константы переводятся очень
;просто, особенно с калькулятором CITIZEN.
;
; Пример: имеется число 0.16.
; Умножаем его на 256, получаем 40.96.
; Округляем до 41.
; Переводим в HEX:  #0029.
;
; Если число <0, то до перевода в HEX к
; нему прибавляем 65536 (#10000).

CONST1  DW    #0000;   A=0
        DW    #0000;   B=0
        DW    #0000;   C=0
        DW    #0000;   D=0
        DW    #0029;   E=.16
        DW    #0000;   F=0


CONST2  DW    #00DA;   A=.85
        DW    #000A;   B=.04
        DW    #0000;   C=0
        DW    #FFF6;   D=-.04
        DW    #00DA;   E=.85
        DW    #019A;   F=1.6


CONST3  DW    #0033;   A=.2
        DW    #FFBD;   B=-.26
        DW    #0000;   C=0
        DW    #003B;   D=.23
        DW    #003B;   E=.23
        DW    #019A;   F=1.6


CONST4  DW    #FFDA;   A=-.15
        DW    #0048;   B=.28
        DW    #0000;   C=0
        DW    #0043;   D=.26
        DW    #003D;   E=.24
        DW    #0071;   F=.44


   Для прикола, в блоке CONST2 можете  1-е
число заменить на #00B0 - получите  нечто,
напоминающее елочку, или  на  #0060 - тоже
вроде елочку, но какую-то ободранную...

;Текущие координаты:
X       DW    #0000
Y       DW    #0000


P.S.  На этом фрактале неплохо тестировать
процедуру получения случайных чисел.  Если
генерируемые им значения часто повторяются
или все время  попадают в определенный ин-
тервал, лежащий внутри [0, 255],  то фрак-
тала не получится  (можете попробовать уб-
рать  ксорку с  (IX), указывающим на ПЗУ -
увидите что будет).
   В идеале все числа  должны быть  равно-
вероятными, попадать в диапазон 0 - 255, а
порядок  их следования  друг за  другом не
должен повторяться и иметь какую-либо тен-
денцию (например бывают процедуры, в кото-
рых следующее число обычно больше предыду-
щего).




Другие статьи номера:

Аперативчик - Об управлении в оболочке DEJA VU

Аперативчик - Точность - вежливость королей; о новом выпуске журнала.

Тема - Fun Top-98 или очевидное и невероятное.

Тема - Интервью с Вл. Балчукеем перед Fun Top-98.

Тема - Результаты Fun Top-98.

Тема - Фоторепортаж с Fun Top-98.

Капля припоя - ПЗУ, которые мы выбираем.Обзор ПЗУ: Penatagon128, Scorpion ZS256,Spectrum128-фирменный вариант,Spectrum+2,Spectrum+2, Spectrum+3, ПЗУ от PROFI CLUB.

Капля припоя - Дополнительный графический режим 512x192.

SOFTWARE - Новинки демосцены: FOREVER, ADRENALIZE, BOOM,TYRANY,BLAME, EMERGENCY, KATNARSIS.

SOFTWARE - Новинки игровых программ: A LAST HERO of the LIGHT FORCE, MONSTR LAND, ЗЕРКАЛО.

CODING - Сверхбыстрое форматирование дисков SPECCY.

CODING - Уроки кодера: Фрактальный папаратник.

CODING - Драйвер чтения/записи.

CODING - Уроки кодера: Генерилка шариков.

CODING - Алгоритмы сжатия информации.

CODING - Об обечатке в листинге использования стека (в 5 номере).

ANOTHER WORLD - WINDOWS-95 и не только.

ANOTHER WORLD - Новости от INTEL-а...

ANOTHER WORLD - РС и работу софта

Доска почета - О спектрумских журналах.

Доска почета - письма в редакцию.

Доска почета - О CD-ROM проекте из города Кемерово.

Семь и 1/2 - Особенности национального рулеза 2 или упорядоченное движение электронов.

Семь и 1/2 - Руководство для потребителей пива.

Семь и 1/2 - Что делать , если не работает компьютер (Инструкция для хаккеров).

Семь и 1/2 - Гадание на таракане (Советы начинающему охотнику).

Семь и 1/2 - Инструкция по пользованию шариковой ручкой.

Проба пера - Стихи А. Баженова: Свечи, Смятение, Осень, Безисходность.

Проба пера - Приключения Винни Пуха (часть 3).

Проба пера - Сутки хаккера обыкновенные.

Реклама - Реклама и объявления ...


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Обзор - Общий обзор прохождения очередной Demo-party ENLiGHT 1997 с фотографиями некоторых гостей.
ZX Spectrum in GDR (DDR) - Spectrum clones history in Germany.
Ликбез - полный дизассемблер ПЗУ (часть 26).

В этот день...   24 сентября