СПЕКТР9М В ШКОЛЕ
Сегодня мы предлагаем материал, который может пригодиться на уроках информатики. Он поможет при изучении операторов Бейсика PLOT и DRAW, Эта программа наглядно продемонстрирует, как, например, буква "А", изображенная в виде отрезков прямых, у Вас на глазах превратится в букву "Б". Можно изображать и более сложные рисунки (см, рисунки в конце статьи), тогда эффект "эволюции" выглядит более зрелищно. В общем, даем слово нашему корреспонденту.
(С) Ульянов A.M.,
г.Великие Луки, 1995.
Предлагаю небольшую программу для создания динамически меняющихся рисунков. Принцип - такой. Два разных изображения составляются из отрезков или точек (точку ведь тоже можно представить, как отрезок, у которого совпадают начальная и конечная координаты). Затем запускается программа и Вы видите, как одно изображение плавно "перетекает" в другое. Вот Бейсик-программа, которая позволит задать два изображения и посмотреть процесс превращения одного в другое (Бейсик-программа приводится с непринципиальными изменениями).
1 BORDER 7: PAPER 7: INK 0: С LS : LET zz=0: LET qq=0 5 OVER 1 10 INPUT "NUMBER of LINES: ";c 12 DIM f(c): DIM e(c): DIM j(c ): DIM 1(c)
15 DIM a(c): DIM b(c): DIM g(c ): DIM d(c)
17 DIM o(c): DIM p(c): DIM r(c ): DIM s(c)
19 GO SUB 400
50 CLS : INPUT "STEP: ";h
53 FOR n=l TO c: LET f(n)=0: L
ЕТ e(n)=0: LET j(n)=0: LET l(n) = 0: NEXT n
55 FOR i=0 TO h 60 FOR n=l TO с
65 LET x=(b(n)-a(n))/h*i+a(n)
66 LET y=(p(n)-o(n))/h*i+o(n)
67 LET xl=(d(n)-g(n))/h*i+g(n)
68 LET yl=(s(n)-r(n))/h*i+r(n) 70 PLOT x,y: DRAW (xl-x),(yl-y
)
72 PLOT f(n),e(n): DRAW (j(n)~ f(n))>(l(n)-e(n))
74 LET f(n)=x: LET j(n)=xl: LE T e(n)=y: LET l(n)«yl 90 NEXT n: PAUSE 10 100 NEXT i
110 PAUSE 0: GO TO 50 400 LET z-0: LET q=0 410 FOR n—1 TO с 420 GO SUB 800: BORDER 0: LET a (n)=z: LET o(n)=q 430 GO SUB 800: BORDER 7: LET g (n)=z: LET r(n)-q 440 PLOT a(n),o(n): DRAW g(n)-a (п) ,г(п)""0(п) 450 NEXT n 455 CLS
460 FOR n=l TO с 470 GO SUB 800: BORDER 0: LET b (n)-z: LET p(n)=q 480 GO SUB 800: BORDER 7: LET d (n)=z: LET s(n)=q
490 PLOT b(n),p(n): DRAW d(n)-b (n),s(n)-p(n) 500 NEXT n 510 RETURN
800 IF INKEY$="6" THEN LET Z=Z -(z>0): GO TO 900
810 IF INKEY$="7" THEN LET Z=Z +(z<255): GO TO 900
820 IF INKEY$="9" THEN LET q=q -(q>0): GO TO 900
830 IF INKEY$="8" THEN LET q=q +(q<l75): GO TO 900
840 IF INKEY$="0" THEN GO TO 1 000
860 GO TO 800
900 PLOT z ,q: PLOT zz,qq: PRINT OVER 0; AT 0,2";AT 0,0;nx= ";z;AT 0,18;" ";AT 0,16;"y=";q 910 LET zz=z: LET qq=q 920 GO TO 800 1000 FOR v=l TO 20: NEXT v: RETU RN
После запуска программы в ответ на запрос "NUMBER OF LINES" введите количество отрезков, из которых Вы будете строить изображения (обычно 3-10). После ввода экран очистится. Попробуйте теперь понажимать клавиши управления SINCLAIR-джойстиком ("6м-"9м). Вы увидите точечный курсор, который будет задавать начальную координату отрезка. Вверху экрана отображаются текущие координаты курсора. Установите курсор в желаемое место и нажмите "0". Бордюр станет черным - это будет начало отрезка. Теперь отметьте курсором конец отрезка и опять нажмите "0м - отрезок появится на экране. Для получения ломаной линии нажмите "0м еще раз - тогда начало следующего отрезка совпадет с концом предыдущего. Когда будет исчерпано заданное число отрезков, экран опять очистится. Теперь Вы должны аналогично задать второй рисунок. После того, как оба рисунка будут заданы, экран вновь очистится и появится новый запрос "STEP" - надо ввести число (10-20) промежуточных изображений, которые будут рассчитаны программой при переходе от начального рисунка к конечному. Нажмите ENTER и Вы увидите процесс эволюции одного изображения в другое.
Назначение некоторых переменных в программе. С - число отрезков, из которых строятся фигуры. При построении фигур переменная z определяет координату курсора по горизонтали, a q - по вертикали.
а(п) - координата X начала п-ного отрезка 1-й фигуры;
о(п) - координата Y начала n-ного отрезка 1-й фигуры;
д(п) - координата X конца п-ного отрезка 1-й фигуры;
г(п) - координата Y конца п-ного отрезка 1-й фигуры;
b(n), р(п), d(n), s(n) - то же для второй фигуры соответственно.
f(n), е(п), j(n) и 1(п) - расчетные координаты для построения промежуточного изображения п-ного отрезка.
Назначение некоторых строк программы.
С Я f |
? К Т Р У и |
в |
ШКОЛЕ 1 |
|
Строка 10 - ввод числа отображаемых отрезков.
12-17 - Создается место для массивов координат точеГк отрезков и ряда промежуточных изображений.
19 - в этой строке выполняется подпрограмма GO SUB 400, которая задает начальное и конечное изображения .
50 - ввод числа промежуточных изображений. После того, как исходные изображения будут заданы и отработаны, программу можно остановить . А чтобы при следующем запуске не повторять утомительный процесс ввода изображений, можно запустить программу именно с этой строки: GO ТО 50.
55-100 - эта часть программы, непосредственно создающая преобразование изображений.
Строка 110 зацикливает программу - Вы можете еще раз посмотреть эффект преобразования с новым значением промежуточных изображений STEP.
400-510 - подпрограмма ввода изображений. Содержит две части: 410-450 - ввод первого рисунка; 460-500 - ввод второго рисунка.
800-1000 - подпрограмма опроса клавиш SINCLAIR-джойстика.
Комментарий ИНЯЮРКОМА,
Как и любая Бейсик-программа, в которой происходят многочисленные вычисления, да еще графика при помощи PLOT-DRAW, эта программа также имеет сравнительно низкое быстродействие. Применение компилятора "TOBOS FP" позволит значительно улучшить скоростные характеристики программы. После компиляции Вы убедитесь, что теперь можно увеличить «4исло промежуточных изображений с 5-10 до 30-60. При этом эволюция происходит достаточно плавно и быстро.
Однако при практическом выполнении компиляции приведенной программы выявились и некоторые недостатки. Так, например, практически невозможно набрать заранее заданную фигуру без ошибок, при ошибке же приходится останавливать программу и повторять весь процесс сначала. Поэтому предлагаем следующий вариант. Программу для ввода изображений сделаем на Бейсике, а для просмотра эффекта - откомпилируем только ту часть программы, которая для этого нужна. Для передачи же данных из одной программы в другую будем использовать не массивы переменных, а непосредственно память компьютера (при помощи РОКЕ и РЕЕК).
Итак, программа для ввода изображений. В основном она соответствует изначальному варианту, за исключением хранения данных.
1 BORDER 7: PAPER 7: INK 0: С LEAR 34999: LET adr»35000: LET Z z»0: LET qq=0: OVER 1
10 INPUT "NUMBER of LINES: M;c : POKE adr,c: LET adr=adr+l
19 GO SUB 400
20 SAVE "data"CODE (adr-l),2*4 *c+l
50 LET adr=35000: LET c=PEEK a dr: LET adr=adr+l
51 INPUT "STEP: ";h: CLS : OVE R 1
52 DIM f(c): DIM e(c): DIM j(c ): DIM 1(c)
53 REM FOR n=l TO c: LET f(n) «0: LET e(n)-0: LET j(n)=*0: LET 1(n)«0: NEXT n
55 FOR i=Q TO h
60 FOR n=0 TO c-1
65 LET x=(PEEK (adr+4*c+4*n)-P EEK (adr+4*n))/h*i+PEEK (adr+4*n )
66 LET ye(PEEK (adr+4*c+4*n+l) -PEEK (adr+4*n+l))/h*i+PEEK (adr +4*n+l)
67 LET xlss(PEEK (adr+4*C+4*n+2 )-PEEK (adr+4*n+2))/h*i+PEEK (ad r+4*n+2)
68 LET yl=(PEEK (adr+4*c+4*n+3 )-PEEK (adr+4*n+3))/h*i+PEEK (ad r+4*n+3)
70 PLOT f(n+1),e(n+l): DRAW (j (n+l)-f(n+1)),(l(n+l)-e(n+l))
72 PLOT x,y: DRAW (xl-x),(yl-y
)
74 LET f(n+1)«x: LET j(n+l)»Xl
: LET e(n+l)«y: LET l(n+l)®yl
90 NEXT n: PAUSE 10: IF i»0 TH EN PRINT #0;" Press any
key...": PAUSE 0: INPUT ; 100 NEXT i 110 GO TO 51 400 LET z=0: LET q=0 410 FOR n=0 TO c-1 420 GO SUB 800: BORDER 0: POKE (adr+4*n),z: POKE (adr+4*n+l),q: LET x=z: LET y«q 430 GO SUB 800: BORDER 7: POKE (adr+4*n+2),z: POKE (adr+4*n+3>, q: LET xl«z: LET ylsq 440 PLOT x,y: DRAW (xl-x),(yl-y
)
450 NEXT n 455 CLS
460 FOR n=l TO с 470 GO SUB 800: BORDER 0: POKE (adr+4*c+4*n),z: POKE (adr+4*c+4 *n+l),q: LET x=z: LET y»q
480 GO SUB 800: BORDER 7: POKE (adr+4*c+4*n+2),z: POKE (adr+4*c +4*n+3),q: LET Xl=z: LET yl=q 490 PLOT x,y: DRAW (xl-x),(yl-y
)
500 NEXT n 510 RETURN
800 IF INKEY$="6" THEN -(z>0): GO TO 900
810 IF INKEY$e"7" THEN +(Z<255): GO TO 900
820 IF INKEY$-"9M THEN -(q>0): GO TO 900
830 IF INKEY$-"8" THEN +(q<175): GO TO 900
840 IF INKEY$="0" THEN 000
860 GO TO 800 900 PLOT z,q: PLOT zz,qq: PRINT OVER 0;AT 0,2;" ";AT 0,0;"x« " ;z;AT 0,18;" ";AT 0,16;"y" ;q 910 LET zz»z: LET qq=q 920 GO TO 800 1000 POKE adr,z: POKE (adr+l),q: LET adr=adr+2: FOR v=l TO 20: N EXT v: RETURN
Массив данных располагается в памяти, начиная с адреса 35000. Первый байт хранит NUMBER OF LINES. С адреса 35001 группами по 4 байта хранятся координаты X и Y начала и конца отрезков в следующем порядке:
LET z»z LET z=z LET q=q LET q»q GO TO 1
Х-коорд. начала 1-го отрезка;
Y-коорд. начала 1-го отрезка;
Х-коорд. конца 1-го отрезка;
Y-коорд. конца 1-го отрезка;
Далее - то же для остальных отрезков первой фигуры; далее -все повторяется для второй фигуры.
После завершения рисования обоих фигур (заполнения кодового массива с заявленным числом отрезков) в строке 20 будет выдан результат - Вы можете сохранить его для использования в будущем.
Затем происходит переход на программу просмотра - строку 50.
Если кодовый массив не задавался непосредственно, а был загружен с внешнего носителя, то Вы можете запустить программу с этой строки RUN 50 (а не GO ТО 50, так как очистка всех переменных на страшна, поскольку данные сохраняются в блоке кодов). Эта часть программы позволит просмотреть промежуточные изображения так, как это делает исходная программа (однако и так же медленно, как исходная программа).
Для более быстрого просмотра наберем и откомпилируем специальную программу:
50 BORDER 7: PAPER 7: INK 0: С LS : LET adr-35000: LET C=PEEK a dr: LET adr=adr+l
51 INPUT "STEP: ";h: CLS : OVE R 1
52 DIM f(с): DIM e(c): DIM j(c ): DIM 1(c)
55 FOR i=0 TO h
60 FOR n=0 TO c-1
65 LET Xs(PEEK (adr+4*c+4*n)-P EEK (adr+4*n))/h*i+PEEK (adr+4*n )
66 LET y=(PEEK (adr+4*c+4*n+l) -PEEK (adr+4*n+l))/h*i+PEEK (adr +4*n+l)
67 LET xl=(PEEK (adr+4*c+4*n+2 )-PEEK (adr+4*n+2))/h*i+PEEK (ad r+4*n+2)
68 LET yl-(PEEK (adr+4*c+4*n+3 )-PEEK (adr+4*n+3))/h*i+PEEK (ad r+4*n+3)
70 PLOT x,y: DRAW (xl-x),(yl-y
)
72 PLOT f(n+1),e(n+l): DRAW (j (n+l)-f(n+l)),(l(n+l)-e(n+l))
74 LET f(n+1)sx; LET j(n+l)»xl : LET e(n+l)-y: LET l(n+l)»yl
90 NEXT n: PAUSE 1: IF i«0 THE N PRINT #0;" Press any k
ey...": PAUSE 0: INPUT ; 100 NEXT i 110 GO TO 51
Теперь откомпилируем ее в адрес 45000 при помощи компилятора ИТ0В08И:
CLEAR 44999
LOAD "TOBOS"CODE 53000
RANDOMIZE USR 53000
На экране увидим примерно такой результат:
RUN > RANDOMIZE USR 45000
SAVE > CODE 45000,1112
Сохраните откомпилированный блок кодов.
Сделайте теперь CLEAR 34999 и загрузите блок данных, набранный ранее: LOAD "data"CODE 35000.
Теперь можно ускоренно увидеть процесс эволюции одного изображения в другое, запустив откомпилированный блок: при помощи RANDOMIZE USR 45000. Можете наблюдать процесс, вводя по запросу различное число промежуточных этапов STEP.
И последнее. Чтобы Вам интереснее было работать, мы предлагаем уже закодированный массив данных. После его ввода и запуска Вы сможете наглядно посмотреть процесс эволюции: рыбья голова на Ваших глазах превратится в голову птицы (см. рисунки на следующей странице).
88В8: IF 9F 6F AD 64 AD 64 В1 :40 88С0: 4А В1 4А А8 29 А8 29 99 :С8 88С8: 1D 99 ID В5 19 В5 19 С4 :83 88D0: 13 С4 13 С4 98 С4 98 А2 :9С 88D8: 88 А2 88 73 82 73 82 4В :47
88Е0 |
72 |
4B |
72 |
40 |
6A |
40 |
6A |
53 |
3E |
8998: 64 1С 88 84 88 84 88 88 :29 |
88Е8 |
61 |
53 |
61 |
66 |
53 |
66 |
53 |
6E |
65 |
89A0: 80 88 80 84 77 84 77 7C :23 |
88F0 |
47 |
6E |
47 |
6E |
3E |
6E |
3E |
62 |
2E |
89A8: 77 7C 77 78 80 78 80 7C :07 |
88F8 |
38 |
62 |
38 |
4F |
46 |
4F |
46 |
39 |
B5 |
89B0: 88 00 00 00 00 00 00 00 :C1 |
8900 |
4C |
39 |
4C |
ЗА |
45 |
ЗА |
45 |
65 |
BD |
|
8908 |
2A |
65 |
2A |
99 |
ID |
40 |
6A |
35 |
DF |
Конечно, приведенный алгоритм |
8 9 ID |
61 |
35 |
61 |
51 |
51 |
51 |
51 |
33 |
07 |
не претендует на истину в послед |
8918 |
57 |
33 |
57 |
39 |
4C |
69 |
75 |
6F |
64 |
ней инстанции. К тому же, неплохо |
8920 |
75 |
6F |
75 |
72 |
6E |
72 |
6E |
6F |
31 |
было бы еще более усхорить работу |
8928 |
67 |
6F |
67 |
69 |
67 |
69 |
67 |
66 |
F4 |
программы - но сделать это можно |
8930 |
6E |
66 |
6E |
69 |
75 |
ВС |
71 |
BE |
C4 |
только полностью перейдя на ма |
8938 |
58 |
BE |
58 |
AF |
44 |
AF |
44 |
9C |
B1 |
шинный код. Возможно, кто-нибудь |
8940 |
3B |
9C |
3B |
7E |
40 |
78 |
39 |
80 |
CA |
из читателей сделает на основе |
8948 |
21 |
80 |
21 |
CD |
21 |
CD |
21 |
CD |
3C |
этой идеи полноценную программу, |
8950 |
93 |
CD |
93 |
9E |
AB |
9E |
AB |
74 |
D2 |
с полноценным редактором рисун |
8958 |
A6 |
74 |
A6 |
50 |
92 |
50 |
92 |
48 |
AD |
ков, с возможностью "отката11 при |
8960 |
87 |
48 |
87 |
53 |
80 |
53 |
80 |
56 |
3B |
неверно введенных координатах. |
8968 |
70 |
56 |
70 |
73 |
62 |
73 |
62 |
5C |
2D |
Или этот эффект украсит чью-то |
8970 |
5D |
5C |
5D |
58 |
50 |
59 |
64 |
39 |
AD |
авторскую программу или найдет |
8978 |
5B |
39 |
5B |
41 |
55 |
41 |
55 |
58 |
74 |
какое-то другое отражение. |
8980 |
50 |
58 |
50 |
6A |
46 |
6A |
46 |
78 |
D9 |
|
8988 |
39 |
48 |
87 |
30 |
77 |
30 |
77 |
2A |
91 |
* * * |
8990 |
55 |
2A |
55 |
37 |
64 |
37 |
64 |
59 |
1С |
|