Поиск:

Ответ в темуСоздание новой темы Создание опроса
> графические примитивы на Ассемблере 
:(
    Опции темы
CreatoR
Дата 24.5.2007, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 8.4.2004

Репутация: нет
Всего: нет



 Нужно средствами асемблера реализовать отрисовку примитивов:
 - Прямоугольник
 - Круг
 - Прямоугольник с заливкой
 - Круг с заливкой

Все эти функции должны вызыватся из С или же просто в него интернированны...

Очень нужно информация по этому вопросу.
желательно с  кодом.
PM MAIL   Вверх
Alexander77
Дата 25.5.2007, 01:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 27.4.2007

Репутация: нет
Всего: нет



Платформа какая (Windows/DOS)? Можно DLL-ку сделать, вызывать будешь на чём нравиццо. Ну и критично ли какой асм (masm/fasm/tasm/what else).
По поводу исходников: самое сложное — круг, поэтому вот что есть "в природе" из кода: http://www.programmersheaven.com/mb/x86_as...eadmessage.aspx
PM MAIL ICQ Skype YIM   Вверх
Mikl__
Дата 25.5.2007, 07:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 18.5.2007

Репутация: 1
Всего: 1



Если под DOS
У окружности координаты любой точки относительно ее центра вычисляются из соотношения R^2=X^2+Y^2, где R радиус окружности. С точки зрения программирования достаточно нарисовать 1/8 часть окружности, а симметрия закончит дело. В языках программирования высокого уровня существует специальная функция CIRCLE, которая строит окружность либо, вычисляя синус, либо, двигаясь например по оси X вычисляет на каждом шаге координату Y по формуле . В языке ассемблера для вычисления квадратного корня или функции синуса пришлось бы использовать обращение к сопроцессору, а такая программа с точки зрения ассемблера работает непозволительно долго. Подумаем, как нам реализовать более быстрый метод рисования окружностей используя только целочисленную арифметику, ведь на экране можно выводить точку только туда, где находится люминофор, а не между люминофорами, или смещать точку на долю микрона вправо или влево. Пусть центр окружности находится в точке (0, 0) Y=R=100 и X=0 по формуле Y2 равен R2-X2. По мере движения по оси X мы должны выяснить, когда нам необходимо уменьшить Y. Это нужно сделать если отклонение от Y будет больше 0,5 величины люминофора, т.е. больше должна засвечиваться соседняя точка. Вычисляем квадрат отклонения: 
(Y-0,5)^2=Y^2-Y+0,25. Выражение Y^2-Y вычисляется в целых числах, а 0,25 игнорируем. Если разность R^2-X^2 больше чем Y^2-Y необходимо уменьшить Y на единицу и опять пересчитать ту величину, когда необходимо будет снова изменить Y и так в цикле. Вы выводите N точек, где N вычисляется из значения L=2*Pi*R. Так как Вам надо нарисовать 1/8 окружности N=L/8=Pi*R/4≈157*R/200.
Код

.286
.model tiny
.code
ORG 100h
.startup
RADIUS EQU 99    ;рисуем окружность с радиусом 99
RADIUS2 EQU RADIUS*RADIUS    ;квадрат радиуса
DIAMETR EQU RADIUS*2        ;диаметр окружности
N EQU 157*RADIUS/200;количество точек на 1/8 
COLOR EQU 10            ;цвет окружности
MOV AH,0Fh    ;узнать номер текущего видеорежима
INT 10h
MOV VIDEOR,AL        ;запомним текущий видеорежим
MOV AX,13h;установить видеорежим 320х200х256 
INT 10h
PUSH 0A000h;установить регистр ES на сегмент 
POP ES            ; видеопамяти
XOR BP,BP            ;будем увеличивать X и Y
MOV Y,RADIUS-1        ;координаты X=0 и Y=R
 CALL DRAW_OCT1    ;рисуем восьмушку окружности
MOV BP,RADIUS-1    ;координата X=2*R
MOV Y,0            ;координата Y=0
CALL DRAW_OCT2    ;рисуем восьмушку окружности
NEG DELTA_X        ;увеличиваем Y и уменьшаем X
MOV Y,RADIUS         
MOV BP,DIAMETR    ;координаты Y=R и X=2*R
CALL DRAW_OCT1    ;рисуем восьмушку окружности
MOV BP,RADIUS        ;координата X=R
MOV Y,0            ;координата Y=0
CALL DRAW_OCT2    ;рисуем восьмушку окружности
NEG DELTA_Y    ;уменьшаем координаты Y и X
MOV Y,RADIUS        ;координата Y=R
MOV BP,DIAMETR    ;координата X=2*R
CALL DRAW_OCT1    ;рисуем восьмушку окружности
MOV BP,RADIUS        ;координата X=R
MOV Y,DIAMETR        ;координата Y=2*R
CALL DRAW_OCT2    ;рисуем восьмушку окружности
NEG DELTA_X    ; уменьшаем Y и увеличиваем X
XOR BP,BP            ;координата X=0
MOV Y,RADIUS        ;координата Y=R
CALL DRAW_OCT1    ;рисуем восьмушку окружности
MOV BP,RADIUS        ;координата X=R
MOV Y,DIAMETR        ;координата Y=2*R
CALL DRAW_OCT2    ;рисуем восьмушку окружности
XOR AX,AX        ;ожидание нажатия любой клавиши
INT 16h
MOV AX,WORD PTR VIDEOR;восстановление видеорежима
INT 10h
RET                ;выход из программы
PROC DELTA_CALC    ;рассчитаем ошибку накопления
MOV BX,AX    ;в AX значение координаты X или Y 
DEC AX            ;вычислим (Y+0,5)2  Y2+Y
MUL AX            ;или (X+0,5)2  X2+X
ADD AX,BX
MOV DELTA,AX    ;и поместим это значение в DELTA
RET
ENDP
;процедура прорисовки 1/8 окружности с вычислением 
PROC DRAW_OCT1    ; координаты X
MOV AX,Y
SHL    AX,6     ;должно быть DI=Y*320, но для умножения 
    MOV    DI,AX    ;на 320 используем сдвиги, AX= Y*64,
    SHL    AX,2    ;сохраним AX в DI и умножим Y*64 на 4
ADD    DI,AX        ;DI=Y*(256+64)=Y*320.
MOV AX,BP             
SUB AX,RADIUS        ;BP=X AX=R-X
CALL DELTA_CALC    ;расчет ошибки накопления по X
MOV CX,N
CIRC1: MOV AX,Y
SUB AX,RADIUS        ;AX=Y-R 
MUL AX
NEG AX
ADD AX,RADIUS2    ;AX=R2-Y2
CMP DELTA,AX    ;сравнить текущий X2=R2-Y2 с ошибкой 
JBE A3    ;накопления, если меньше, увеличиваем или 
ADD BP,DELTA_X;уменьшаем только Y, иначе 
MOV AX,BP;увеличиваем или уменьшаем еще и X и 
SUB AX,RADIUS; вычисляем новую ошибку накопления
CALL DELTA_CALC
A3:    CMP DELTA_Y,1
JNE A1
ADD DI,320
JMP SHORT A2
A1:    SUB DI,320
A2:    MOV BYTE PTR ES:[DI][BP],COLOR;выводим точку на 
MOV AX,DELTA_Y; экран
ADD Y,AX
LOOP CIRC1    ;повторяем цикл
RET
ENDP
;процедура прорисовки 1/8 окружности с вычислением 
PROC DRAW_OCT2    ; координаты X
MOV AX,Y
SHL    AX,6     ;должно быть DI=Y*320, но для умножения 
    MOV    DI,AX    ;на 320 используем сдвиги, AX= Y*64,
    SHL    AX,2    ;сохраним AX в DI и умножим Y*64 на 4
ADD    DI,AX        ;DI=Y*(256+64)=Y*320.
MOV AX, Y            
SUB AX,RADIUS
CALL DELTA_CALC
MOV CX,N
CIRC2: MOV AX,BP
SUB AX,RADIUS
MUL AX
NEG AX
ADD AX,RADIUS2    ;AX=R2-(X-R)2
CMP DELTA,AX
JBE A5
MOV AX,DELTA_Y
ADD Y,AX
MOV AX,Y
SUB AX,RADIUS
CALL DELTA_CALC
CMP DELTA_Y,1
JNE A4
ADD DI,320
JMP SHORT A5
A4:    SUB DI,320
A5:    ADD BP,DELTA_X
MOV BYTE PTR ES:[DI][BP],COLOR
LOOP CIRC2
RET
ENDP
VIDEOR DB 0,0    ;значение текущего видеорежима
DELTA    DW    0    ;ошибка накопления
DELTA_X    DW    1    ;смещение по оси X
DELTA_Y    DW    1    ;смещение по оси Y
Y    DW    0        ;координата Y
END
.
Данная программа выводит на экран окружность, заданного радиуса и цвета, с центром, определенным координатами (R, R). Скорость прорисовки окружности можно увеличить, если не вычислять координату в каждой точке, а вычислять координаты только в начале рисования 1/8 окружности, а далее прибавлять или вычитать 1 к содержимому регистра BP при изменении координаты X и прибавлять или вычитать 320 (длина строки в режиме 13h (320x200x256)) к содержимому регистра DI при изменении координаты Y. Также для увеличения скорости умножение координаты Y на 320 заменено на операции сдвига и сложения.

PM MAIL   Вверх
Mikl__
Дата 25.5.2007, 07:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 18.5.2007

Репутация: 1
Всего: 1



Для рисования окружности, круга под Win-32 используется функция WinAPI Ellipse 
Описание: function Ellipse(DC: HDC, X1, Y1, X2, Y2: Integer): Bool;
Рисует эллипс, центpиpованный в огpаничивающем пpямоугольнике, гpаница котоpого
наpисована текущим пеpом и заполнена текущей кистью
Паpаметpы: DC: Идентификатоp контекста устpойства.
X1, Y1: Веpхний левый угол огpаничивающего пpямоугольника.
X2, Y2: Пpавый нижний угол огpаничивающего пpямоугольника.
Возвpащаемое значение: Не нуль, если эллипс наpисован; нуль - в пpотивном случае.
функция находится в файле gdi32.dll
Если элипс вписать в квадрат будет круг. Окружность будет нарисована цветом текущего пера (по умолчанию черный), заполнена текущей кистью (по умолчанию белой)
Для отрисовки прямоугольника или прямоугольника с заливкой используй функцию WinAPI Rectangle
Описание: function Rectangle(DC: HDC, X1, Y1, X2, Y2: Integer): Bool;
Рисует пpямоугольник, используя выбpанное пеpо, и закpашивает его внутpенность с
помощью текущей выбpанной кисти.
Паpаметpы: DC: Идентификатоp контекста устpойства.
X1, Y1: Веpхний левый угол пpямоугольника.
X2, Y2: Пpавый нижний угол пpямоугольника.
Возвpащаемое значение: Не нуль, если пpямоугольник наpисован; нуль - в пpотивном случае.
функция находится в файле gdi32.dll

PM MAIL   Вверх
LITEOMILL
Дата 24.1.2023, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 23.1.2023

Репутация: нет
Всего: нет




Модератор: Сообщение скрыто.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm: Общие вопросы"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1045 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.