Столкнулся с такой проблемой существующих процедур рисования окружности, которые можно, в частности, найти здесь на форуме. Например, алгоритм из "Библии демомейкера" в OVER 1 рисует такую окружность:
Столкнулся с такой проблемой существующих процедур рисования окружности, которые можно, в частности, найти здесь на форуме. Например, алгоритм из "Библии демомейкера" в OVER 1 рисует такую окружность:
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
То есть некоторые точки рисуются по два раза. И даже если вообще никто не рисует окружности в режиме OVER 1, то всё равно это - потеря производительности.
Стандартная ПЗУ'шная процедура такой проблемы не имеет.
Хотелось бы найти быструю и корректную в этом смысле процедуру. Что посоветуете?
Решил пока воздержаться от изобретания велосипеда, - вот нашёл:
http://icereijo.com/a-circle-algorithm-for-zx-spectrum/
там и исходники, и тапка, и видео даже.
С уважением,
Gris / Red Triangle.
_____________________________________
ZX-EVO/TS-Labs config/NGS/HDD/SD-card
Amiga A1200/Blizzard 1230@50/32/60GB
Amiga A1200/Apollo 1260@66/32/60GB
UnAmiga (C5) AGA GM7123 VideoDAC
Эврика. Выбранная тобой процедура, используя свойства симметрии, рисует точки по октетам. При одной из координат равной 0, количество вариантов расположения точек вырождается до 4-х: смещения от оси симметрии равны +0/-0. Поэтому точки при этом рисуются на одном и том же месте. Избежать этого можно, если для случаев x=0 / y=0 сделать специальные п/п рисования точек.
С уважением,
Gris / Red Triangle.
_____________________________________
ZX-EVO/TS-Labs config/NGS/HDD/SD-card
Amiga A1200/Blizzard 1230@50/32/60GB
Amiga A1200/Apollo 1260@66/32/60GB
UnAmiga (C5) AGA GM7123 VideoDAC
shurik-ua, спасибо конечно. Но уточню: мне нужна не теория и алгоритм на псевдобейсике, а нормальный отлаженный код на ассемблере Z80. Или совет как пофиксить упомянутые выше процедуры.
Вторую хотелось бы отладить особенно, потому что она редкостная - большинство процедур, которые я здесь встречал, имеют однобайтовые аргументы.
Есть у меня ещё одна процедура (не помню откуда брал), интересная тем, что радиус можно задавать двухбайтовым числом. И можно рисовать за пределами экрана.
Скрытый текст
Код:void Basic_CIRCLEW_EI (unsigned char cx, unsigned char cy, int radius) __naked { __asm LD IY, #0x5C3A POP DE POP BC ; BC = YX POP HL ; HL = radius PUSH HL PUSH BC PUSH DE LD A, H OR L RET Z BIT 7, H RET NZ PUSH IX DI LD D, #0 LD E, C LD C, B LD B, D PUSH DE LD DE, #0 PUSH DE PUSH BC PUSH HL LD IX, #0 ADD IX, SP PUSH HL EXX POP HL ADD HL, HL EX DE, HL LD HL, #3 AND A SBC HL, DE EXX JR ENT1$ CIRCLOOP1$: AND A SBC HL, DE JP M, EXT1$ POP DE POP HL ADD HL, DE EX DE, HL POP BC POP HL ADD HL, BC LD SP, IX CALL WRAP1$ POP BC POP HL POP DE ADD HL, DE EX DE, HL POP HL ADD HL, BC LD SP, IX CALL WRAP1$ POP DE POP HL AND A SBC HL, DE EX DE, HL POP BC POP HL AND A SBC HL, BC LD SP, IX CALL WRAP1$ POP BC POP HL POP DE AND A SBC HL, DE EX DE, HL POP HL AND A SBC HL, BC LD SP, IX CALL WRAP1$ ENT1$: POP DE POP HL ADD HL, DE EX DE, HL POP BC POP HL AND A SBC HL, BC LD SP, IX CALL WRAP1$ POP BC POP HL POP DE ADD HL, DE EX DE, HL POP HL AND A SBC HL, BC LD SP, IX CALL WRAP1$ POP DE POP HL AND A SBC HL, DE EX DE, HL POP BC POP HL ADD HL, BC LD SP, IX CALL WRAP1$ POP BC POP HL POP DE LD (POSITIV1$+1), DE AND A SBC HL, DE EX DE, HL POP HL ADD HL, BC LD SP, IX CALL WRAP1$ EXX EX DE, HL BIT 7, D JR Z, POSITIV1$ LD HL, (POSITIV1$+1) ADD HL, HL ADD HL, HL LD BC, #6 JR CALCDONE1$ POSITIV1$: LD HL, #0 POP BC DEC BC PUSH BC AND A SBC HL, BC ADD HL, HL ADD HL, HL LD BC, #0xA CALCDONE1$: ADD HL, BC ADD HL, DE EXX POP HL POP DE POP DE INC DE PUSH DE LD SP, IX JP CIRCLOOP1$ EXT1$: LD HL, #8 ADD HL, SP LD SP, HL POP IX EI RET WRAP1$: LD A, D OR A RET NZ LD A, H OR A RET NZ LD A, E CP #0xB0 RET NC LD B, E LD C, L JP 0x22E5 __endasm; }[свернуть]
Но у неё та же проблема:
Возможно рисует по две точки как раз из за упрощения/ускорения рисования, просто пожертвовали лишними проверками или точностью алгоритма
Мы хотим получить круто оптимизированный код на ассемблере, чтобы он прямо пиксель в пиксель повторял результат рисования бейсиковского круга? Или можно немножко переставить пикселки в углах, главное чтобы два раза в одном месте не рисовалось, и смотрелось правильно?
Вход определим. X,Y,Z- целые? байт? слово(2 байта) со знаком?
Результат:
На весь экран? (256x192)
Круг частично выходит за экран?
Атрибуты красим? (инк, папер, яркость мигание)
Как опции можно сделать круги с заливкой. Нужно?
Фикс Destr'а рабочий и, в принципе, меня устраивает. Благодарю!
Думаю, можно.
Сейчас у меня просто стоит задача получить хоть какую-то окружность в OVER 1. Но в общем-то:
1. Для библиотеки Basic (ZXDev) нужна процедура окружности. CIRCLEROM там уже есть. CIRCLE задумана как то же самое, но быстрый вариант (все параметры - беззнаковые байты) и не позволяет рисовать за пределами экрана. CIRCLEW - то же самое, но все параметры - слова со знаком. Такой процедуры я не нашёл, поэтому пока удовольствовался процедурой, где координаты - байты без знака, а радиус - слово со знаком. Она умеет рисовать за пределами экрана не всю окружность, а только её часть.
Можно поспорить с тем, нужна ли CIRCLEW непосредственно в библиотеке Basic, но уже пускай будет - по аналогии с RND (результат - байт) и RNDW (результат - слово).
2. Для библиотеки Gfx, которую я недавно начал формировать, пригодились бы и другие варианты окружности, в т.ч. и залитой. Так что буду благодарен.
Последний раз редактировалось Oleg N. Cher; 17.09.2015 в 19:17.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)