0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
1

Рисование по алгоритму DDA-линии

16.11.2010, 18:20. Показов 2763. Ответов 19
Метки нет (Все метки)

пытаюсь написать программу, которая выводит прямую у=кх+b по алгоритму DDA-линии(вроде так называеться). Только у меня известны начальные точки, длина прямой и коэффициент К. Написал вроде, но проблема теперь в том что меняя коэффициент К наклон линии не меняется, подскажите плз в чем проблема?

З.Ы Это мой первый опыт работы с соопроцессором FPU, поэтому просьба сильно не ругаться)

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
.data
k dt 2.4
x1 dw 50 ; начальная х
y1 dw 50 ; начальная у
y2 dw 0
y3 dw 0
.code
start:
mov ax,@data
mov ds,ax
xor ax,ax
 
mov ah,0    
mov al,0fh  ;нвыбор графического режима
int 10h
 
push x1
finit
fild x1  ;загрузка x1 в стек сопроцессора
fld k   ;загрузка k в стек сопроцессора
Fmul st(0),st(1)   ;st0=x1=k*x1
fild y1  ;загрузка y1 в стек сопроцессора
Fsub st(2),st(0)  ;y1=y1-kx1
frndint   ;округляем число 
fistp y2 ;загружаем число в переменную temp
fmul     ;умножает целочисленное слово на st0.
pop x1
mov cx,100 ;длинна 
 
print:
push cx
 
push x1
fild x1 ;загрузка x1 в стек сопроцессора
fld k   ;загрузка k в стек сопроцессора
Fmul st(0),st(1)   ;st0=x1=k*x1
fild y1  ;загрузка y1 в стек сопроцессора
fadd st(0),st(2)  ;y1=y1+kx1
fistp y3 ;достаем полученное число в переменную у3
pop x1
 
mov cx,x1
mov dx,y3
mov ah,0ch  ;рисование точки
mov al,1    ;цвет
;mov bh,0   ;видеостраница
    
int 10h
inc x1
pop cx
loop print
 
mov ax,4c00h
int 21h
end start
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.11.2010, 18:20
Ответы с готовыми решениями:

Алгоритм DDA для линии
Как это на Python переписать: procedure DrawLine(); begin while true do begin ...

Объясните,пожалуйста,алгоритм DDA-линии
В-общем,в своей программе пришлось использовать этот алгоритм,он был взят отсюда:...

Рисование дополнительной линии под углом к основной линии
Доброго времени суток, всем. Помогите решить вопрос. Есть макрос рисующий линию между двумя...

Линии по алгоритму Брезенхема
В общем требуется рисовать линии с помощью клика мыши. Рисует только в определённых областях (видно...

19
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 12:35 2
Ebis, для данной задачи fpu не так уж нужен так как координаты пикселов экрана имеет всегда целочисленное значение Y=2.4*X=(12*X)/5 а чтобы правильно происходило округление Y = (12*X)/5 + 0.5=(24*X+5)/10
0
0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
17.11.2010, 12:50  [ТС] 3
у меня К здесь для примера равен 2.4, а вообще К это TgФ, а тангенст может иметь любое значение, хоть 0.00001 и тогда округление в таком случае будет другое
0
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 12:54 4
Ebis, наверное рисуешь окружность? И всё равно координаты Х и Y целочисленные
алгоритма DDA-линии применяется в случае если использование переменных с плавающей запятой (float,double и т.п.) невозможно в виду каких либо ограничений
0
0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
17.11.2010, 13:02  [ТС] 5
Да нет, у меня задание нарисовать квадрат который будет повернут на угол заданный пользователем, я пытаюсь нарисовать прямую(левое ребро квадрата) повернутого на угол, переделал код, но все как то странно рисуеться, не могу пока ошибку найти
0
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 13:06 6
Ebis, поищи Роджерс Д. Алгоритмические основы машинной графики
Алгоритм Брезенхэма
Алгоритм Ву там примеры
0
0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
17.11.2010, 13:11  [ТС] 7
да я все это читал уже, мне надо именно DDA-алгоритм, вот вроде запрограмировал его а чота коряво рисует
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
.model  small
.stack  100h
.data
.data
k dt 1.0
x1 dw 50 ; начальная х
y1 dw 50 ; начальная у
b dw 0
y3 dw 0
.code
start:
mov     ax,@data
mov     ds,ax
xor     ax,ax
 
mov ah,0        
mov al,0fh      ;выбор графического режима
int 10h
 
push x1
finit
fild x1  ;загрузка x1 в стек сопроцессора
fld k   ;загрузка k в стек сопроцессора
Fmul st(0),st(1)   ;st0=x1=k*x1
fild y1  ;загрузка y1 в стек сопроцессора
Fsub st(0),st(1)  ;y1=y1-kx1
frndint   ;округляем число 
fistp b ;загружаем число в переменную b
;fmul     ;умножает целочисленное слово на st0.
pop x1
mov cx,100 ;длинна 
 
print:
push cx
 
push x1
fild x1 ;загрузка x1 в стек сопроцессора
fld k   ;загрузка k в стек сопроцессора
Fmul st(0),st(1)   ;st0=x1=k*x1
fild b  ;загрузка y1 в стек сопроцессора
fadd st(0),st(1)  ;y1=y1+kx1
frndint   ;округляем число 
fistp y3 ;достаем полученное число в переменную у3
pop x1
 
mov cx,x1
mov dx,y3
mov ah,0ch      ;рисование точки
mov al,1        ;цвет
;mov bh,0       ;видеостраница
        
int 10h
inc x1
pop cx
loop print
 
mov     ax,4c00h
int     21h
end     start
0
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 13:28 8
Ebis, перед выходом из программы необходимо восстанавливать графический режим, который был до запуска программы, для быстрого рисования лучше пользоваться прямым изменением точек в видеопамяти, а не установкой точки через функцию 10h прерывания и лучше выбери 13h режим (320х200х256 цветов) вместо режима 0Fh (640х350х3 цвета) он лучше для понимания и поддерживается Windows а вот 0Fh может и не поддерживаться, я думаю, что ты не с дискетки загружаешься а работаешь в режиме эмуляции DOS?
0
0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
17.11.2010, 13:45  [ТС] 9
да запускаю через DOSBOX, ну от выбора режима суть ошибки не измениться, а как востановить графический режим?
0
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 13:46 10
Ebis, посмотри файл во вложении
очень даже изменится, я сам убедился что эмуляция поддерживает не все режимы
получить текущий режим функцией 0Fh прерывания 10h
сохранить его в переменную
установить требуемый режим функцией 0 прерывания 10h
перед выходом установить старый режим
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.286
.model tiny
.code
    ORG 100h
.startup
MOV AH,0Fh  ;запомнить текущий видеорежим
    INT 10h
MOV VIDEOR,AL;видеорежим в переменную videor
MOV AX, 0013h   ;установить видеорежим 13h
INT 10h
PUSH 0A000h ;установить регистр ES на сегмент 
POP ES  ;видеопамяти
MOV DI,0    ;Установка точки (0, 0) зеленого цвета
MOV CX,0        ;в левый верхний угол экрана
MOV DL,2
CALL DRAW_PIXEL
MOV DI,160  ;Установка точки (160,100) красного 
MOV CX,100  ; цвета в центр экрана
MOV DL,4
CALL DRAW_PIXEL
MOV DI,319  ;Установка точки (319, 199) белого 
MOV CX,199  ; цвета в правый нижний угол экрана
MOV DL,7
CALL DRAW_PIXEL
XOR AX,AX       ;ожидание нажатия любой клавиши
INT 16h
MOV AH,0        ;восстановление видеорежима
MOV AL,VIDEOR
INT 10h
ret         ;выход из программы
;процедура вывода точки на экран
;DI — X координата точки (от 0 до 319)
;CX — Y координата точки (от 0 до 199)
;DL — цвет точки
PROC NEAR DRAW_PIXEL
;присвоить регистру AX значение горизонтального 
;разрешения 
MOV AX,320  ;умножение координаты Y на горизонтальное 
MUL CX      ;разрешение. Результат умножения в AX
MOV BX,AX   ;сложить с координатой X
MOV ES:[BX][DI],DL;вывести точку на экран
RET         ;выход из процедуры
ENDP            ;конец процедуры
VIDEOR DB ? ;переменная для хранения значения 
;текущего видеорежима
END         ;конец программы
Вложения
Тип файла: pdf chirikov.pdf (1.09 Мб, 44 просмотров)
1
0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
17.11.2010, 13:57  [ТС] 11
ладно спасибо, буду пробовать

Добавлено через 3 минуты
скопировал присланный код, скомпилировал и ничего не выходит, ничего не рисует
0
2013 / 1285 / 61
Регистрация: 05.06.2010
Сообщений: 2,213
17.11.2010, 14:00 12
Ebis, у вас проблема с форматом данных. dw(слово) нельзя загружать в сопроцессор - такой формат не поддерживается, минимум dd. Вот немного переделал ваш код:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
.8087
.model  small
.stack  100h
.data
.data
k dd 1.0
x1 dd 50 ; начальная х
y1 dd 50 ; начальная у
b dd 0
y3 dd 0
.code
start:
mov     ax,@data
mov     ds,ax
xor     ax,ax
 
mov ah,0        
mov al, 13h;0fh      ;выбор графического режима
int 10h
 
finit
fild x1  ;загрузка x1 в стек сопроцессора
fld dword ptr k   ;загрузка k в стек сопроцессора
Fmul   ;st0=x1=k*x1
fild y1  ;загрузка y1 в стек сопроцессора
Fsub  ;y1=y1-kx1
frndint   ;округляем число 
fistp b ;загружаем число в переменную b
;fmul     ;умножает целочисленное слово на st0.
 
mov cx,100 ;длинна 
print:
push cx
 
fild x1 ;загрузка x1 в стек сопроцессора
fld dword ptr k   ;загрузка k в стек сопроцессора
Fmul   ;st0=x1=k*x1
fild b  ;загрузка y1 в стек сопроцессора
fadd ;y1=y1+kx1
frndint   ;округляем число 
fistp y3 ;достаем полученное число в переменную у3
 
mov cx, word ptr [x1+2]
mov dx, word ptr [y3+2]
mov ah, 0ch      ;рисование точки
mov al, 1        ;цвет
;mov bh,0       ;видеостраница
        
int 10h
inc word ptr [x1+2]
pop cx
loop print
 
xor ax, ax
int 16h
 
mov     ax,4c00h
int     21h
end     start
1
0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
17.11.2010, 14:04  [ТС] 13
для теста поставил к=10, и вывело мне огого чо))))но все равно спасибо), и не могу понять почему теперь рисует из точки (0,0)?
0
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 14:13 14
Цитата Сообщение от Ebis Посмотреть сообщение
скопировал присланный код, скомпилировал и ничего не выходит, ничего не рисует
у меня рабочий и проверенный COM- файл, а ты наверное компилируешь как ЕХЕ наверное поэтому и не работает
0
2013 / 1285 / 61
Регистрация: 05.06.2010
Сообщений: 2,213
17.11.2010, 14:15 15
вы уверены что правильно реализован алгоритм?
0
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 14:20 16
vital792, вы бы ник указывали к кому обращаетесь, ко мне или к Ebis,
Цитата Сообщение от vital792
вы уверены что правильно реализован алгоритм?
трудно объяснить начинающему, что нужно разбить большую задачу на кучу маленьких и лишь убедившись, что каждая из них работает собрать из них одну большую
0
2013 / 1285 / 61
Регистрация: 05.06.2010
Сообщений: 2,213
17.11.2010, 14:29 17
Mikl___, я не заметил что вы написали сообщение и думал что отвечаю на последнее. Адресовано было Ebis. Я тоже немного поторопился, у меня есть ошибки, но даже если их исправить, че то странное получается. До цикла вычисляется y1=y1-kx1. Тест с k=10: y1 = 50 - 50*10 = -450 - что то не так в самом алгоритме.
0
Ушел с форума
Автор FAQ
15035 / 7230 / 901
Регистрация: 11.11.2010
Сообщений: 12,983
17.11.2010, 14:34 18
vital792, могу только посоветовать Ebis запастись терпением и воспользоваться дебагером, также помогает написание аналогичной программы на каком-нибудь ЯВУ (Pascal, C/C++ и т.д.), чтобы удостовериться, что алгоритм правильный
PS Только, что убедился, что моя программа под "чистым" DOS-ом работает, а при эмуляции DOS'a нет
0
2013 / 1285 / 61
Регистрация: 05.06.2010
Сообщений: 2,213
17.11.2010, 14:40 19
vital792, могу только посоветовать Ebis запастись терпением и воспользоваться дебагером, также помогает написание аналогичной программы на каком-нибудь ЯВУ (Pascal, C/C++ и т.д.), чтобы удостовериться, что алгоритм правильный
поддерживаю - я так обычно и делаю когда есть сомнения. Ассемблер больше для оптимизации, чем для разработки, хотя о какой оптимизации может идти речь если точка выводится 10h прерыванием только уменьшение размера
0
0 / 0 / 0
Регистрация: 03.03.2010
Сообщений: 94
17.11.2010, 19:48  [ТС] 20
Цитата Сообщение от vital792 Посмотреть сообщение
Mikl___, я не заметил что вы написали сообщение и думал что отвечаю на последнее. Адресовано было Ebis. Я тоже немного поторопился, у меня есть ошибки, но даже если их исправить, че то странное получается. До цикла вычисляется y1=y1-kx1. Тест с k=10: y1 = 50 - 50*10 = -450 - что то не так в самом алгоритме.
там не y1=y1-kx1, это опечатка в коментариях, там b=y1-kx1, так как парямая в виде y=kx+b
Спасибо за совет, попробую написать этот же алгоритм на С++!)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.11.2010, 19:48

Рисование прямой по алгоритму Брезенхема
Добрый день. Мне очень нужен исходник программы, которая рисует прямую по алгоритму Брезенхема....

рисование линии
С клавиатуры вводятся координаты 2 линий. Если угол между ними 90±10 градусов, то вывести...

Рисование линии
Подскажите почему у меня не рисуется линия на элементе PictureBox (mainPicture) при нажатии на...

Рисование линии
Цитирую дословно из Петцольда: LineTo(hdc, xEnd, yEnd); Эта функция рисует отрезок до точки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru