Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 06.06.2018
Сообщений: 6

Рисование прямой, параллельной одной из осей координат, при помощи мыши

08.12.2018, 17:56. Показов 1348. Ответов 7

Студворк — интернет-сервис помощи студентам
Необходимо разработать программу, рисующую прямую по двум точкам (первый и второй клики левой кнопкой мыши), прямая должна становиться параллельной одной из осей координат, в зависимости от того как нарисована. Добавить возможность перемещения прямой (либо перемещением с помощью курсора, либо просто кликом по месту, куда необходимо переместить).
Программа рисующая прямую по двум точкам:
Код программы:
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
.model small, Pascal
 
.stack 100h
 
.data
        CrLf            db      0Dh, 0Ah, '$'
        msgPressAnyKey  db      'Press any key to exit...', '$'
        ;Параметры курсоров мыши
        ;Курсор - перекрестие
        MouseCursor_Cross               dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh  ;screen mask (AND mask)
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      00100h, 00100h, 00100h, 00000h  ;cursor mask (XOR mask)
                                        dw      00100h, 00100h, 00000h, 0ED6Eh
                                        dw      00000h, 00100h, 00100h, 00000h
                                        dw      00100h, 00100h, 00100h, 00000h
                                        dw      7                               ;column of cursor hot spot in bitmap (-16 to 16)
                                        dw      7                               ;row of cursor hot spot (-16 to 16)
 
        MouseInitOk                     equ     0FFFFh  ;инициализация мыши - успешна
        MouseInitFault                  equ     0000h   ;инициализация мыши - мышь или драйвер мыши не установлены
 
        MouseButtons_Any                equ     0000h   ;количество кнопок у мыши - отлично от 2 и 3
        MouseButtons_2                  equ     0002h   ;количество кнопок у мыши - 2
        MouseButtons_2_                 equ     0FFFFh  ;количество кнопок у мыши - 2
        MouseButtons_3                  equ     0003h   ;количество кнопок у мыши - 3
 
        ;сообщения программы
        msgMouseFault                   db      'The mouse or mouse driver was not detected.', 13, 10, '$'
        ;
        LineColor                       dw      4
;.data?
        Xbegin                          dw      ?
        Ybegin                          dw      ?
        Xfinish                         dw      ?
        Yfinish                         dw      ?
 
.code
 
;----------------------------------------------
;вызовы функций работы с мышью обернуты в макросы
;----------------------------------------------
;Инициализация работы с "мышью"
;Выполняется аппаратный и программный сброс мыши и драйвера
;вход
; - нет
;выход
;ax - результат инициализации
;   - 0000h, если мышь или драйвер мыши не установлены
;   - FFFFh, если драйвер и мышь установлены
;bx - число кнопок
;   - 0002 или FFFF - две
;   - 0003 - три
;   - 0000 - другое количество
MouseInit       macro
        mov     ax,     0000h
        int     33h
endm
 
;Показать курсор "мыши"
;вход
; - нет
;выход
; - нет
MouseShowCursor macro
        push    ax
        mov     ax,     0001h
        int     33h
        pop     ax
endm
 
;Спрятать курсор "мыши"
;вход
; - нет
;выход
; - нет
MouseHideCursor macro
        push    ax
        mov     ax,     0002h
        int     33h
        pop     ax
endm
 
;установить курсор мыши в графическом режиме
;Определение курсора мыши в графическом режиме
;int 33h ax=0009h:
;BX = column of cursor hot spot in bitmap (-16 to 16)
;CX = row of cursor hot spot (-16 to 16)
;ES:DX -> mask bitmap
;Format of mouse mask bitmap:
;Offset Size            Description
;00h    16 WORDs        screen mask
;10h    16 WORDs        cursor mask
;Note: Each word defines the sixteen pixels of a row, low bit rightmost
MouseSetCursor  macro   Cursor
        push    ax
        push    bx
        push    cx
        push    es
 
        mov     bx,     word ptr [Cursor+64]
        mov     cx,     word ptr [Cursor+66]
        mov     ax,     seg Cursor
        mov     es,     ax
        mov     dx,     offset [Cursor]
        mov     ax,     0009h
        int     33h
 
        pop     es
        pop     cx
        pop     bx
        pop     ax
endm
 
main    proc
        ;инициализация сегментного регистра ds адресом сегмента данных
        mov     ax,     @data
        mov     ds,     ax
 
        ;попытка инициализации мыши
        MouseInit
        cmp     ax,     MouseInitOk
        je      @@MouseInitOk
        ;если инициализация не удалась - вывести сообщение
        ;и завершить программу
        mov     ah,     09h
        lea     dx,     msgMouseFault
        int     21h
        jmp     @@Exit
 
@@MouseInitOk:
        ;установка графического режима
        mov     ax,     0013h
        int     10h
        ;установка формы курсора в графическом режиме
        MouseSetCursor  MouseCursor_Cross
        ;показать курсор
        MouseShowCursor
@@WaitForStartPoint:
        mov     ax,     0003h   ;RETURN POSITION AND BUTTON STATUS
        int     33h
        and     bx,     0001h   ;проверка нажатия ЛКМ
        jz      @@WaitForStartPoint
        ;для графического видеорежима 13h нужно
        ;разделить на 2 координату X курсора
        shr     cx,     1
        mov     [Xbegin],       cx
        mov     [Ybegin],       dx
 
        MouseHideCursor
        mov     ah,     0Ch
        mov     al,     byte ptr [LineColor]
        mov     bh,     0
        mov     cx,     [Xbegin]
        mov     dx,     [Ybegin]
        int     10h
        MouseShowCursor
 
@@WaitForReleaseButton:
        mov     ax,     0003h   ;RETURN POSITION AND BUTTON STATUS
        int     33h
        and     bx,     0001h   ;проверка нажатия ЛКМ
        jnz     @@WaitForReleaseButton
 
@@WaitForFinishPoint:
        mov     ax,     0003h   ;RETURN POSITION AND BUTTON STATUS
        int     33h
        and     bx,     0001h   ;проверка нажатия ЛКМ
        jz      @@WaitForFinishPoint
        ;для графического видеорежима 13h нужно
        ;разделить на 2 координату X курсора
        shr     cx,     1
        mov     [Xfinish],      cx
        mov     [Yfinish],      dx
 
        ;спрятать курсор
        MouseHideCursor
 
        ;нарисовать линию
        push    word ptr [Xbegin]
        push    word ptr [Ybegin]
        push    word ptr [Xfinish]
        push    word ptr [Yfinish]
        push    word ptr [LineColor]
        call    DrawLine
        ;Завершение программы
@@Exit:
        ;ожидание нажатия любой клавиши
        mov     ah,     09h
        lea     dx,     [msgPressAnyKey]
        int     21h
 
        mov     ah,     00h
        int     16h
 
        mov     ax,     4C00h
        int     21h
main    endp
 
DrawLine        proc
        arg xStart:WORD, yStart:WORD, xEnd:WORD, yEnd:WORD, Color:WORD
        ;начало отрезка
        ;конец отрезка
        ;цвет отрезка
 
        ;LOCAL  a, b:WORD       ;  // displacements in x and y
        ;di LOCAL       d:WORD          ;  // decision variable
        LOCAL   diag_inc:WORD   ;  // d's increment for diagonal steps
        LOCAL   dx_diag:WORD    ;  // diagonal x step for next pixel
        LOCAL   dx_nondiag:WORD ;  // nondiagonal x step for next pixel
        LOCAL   dy_diag:WORD    ;  // diagonal y step for next pixel
        LOCAL   dy_nondiag:WORD ;  // nondiagonal y step for next pixel
        ;LOCAL  i:WORD          ;  // loop index
        LOCAL   nondiag_inc:WORD;  // d's increment for nondiagonal steps
        ;swap       :  integer;  // temporary variable for swap
        ;si, dx x,y        :  integer;  // current x and y coordinates
        ;// line starting point
        mov     si,     [xStart]        ;x := xStart;
        mov     dx,     [yStart]        ;y := yStart;
        ;// Determine drawing direction and step to the next pixel.
        ;// difference in x dimension
        mov     ax,     [xEnd]          ;a := xEnd - xStart;
        sub     ax,     [xStart]
        ;// Determine whether end point lies to right or left of start point.
        mov     [dx_diag],      1
        jns     @@StoreA                ;if a < 0 then // drawing towards smaller x values?
                                        ;begin
                neg     ax              ;   a := -a;   // make 'a' positive
                                        ;   dx_diag := -1
                mov     [dx_diag],      -1
                                        ;end
                                        ;else
                                        ;   dx_diag := 1;
        @@StoreA:
        ;// difference in y dimension
        mov     bx,     [yEnd]          ;b := yEnd - yStart;
        sub     bx,     [yStart]
        ;// Determine whether end point lies above or below start point.
        mov     [dy_diag],      1
        jns     @@StoreB                ;if b < 0 then // drawing towards smaller y values?
                                        ;begin
                neg     bx              ;   b := -b;   // make 'b' positive
                                        ;   dy_diag := -1
                mov     [dy_diag],      -1
                                        ;end
                                        ;else
                                        ;   dy_diag := 1;
        @@StoreB:
                                        ;// Identify octant containing end point.
        cmp     ax,     bx              ;if a < b then
        jae     @@A_ge_B                ;begin
                mov     cx,     ax      ;   swap := a;
                mov     ax,     bx      ;   a := b;
                mov     bx,     cx      ;   b := swap;
                mov     [dx_nondiag],0  ;   dx_nondiag := 0;
                mov     cx,[dy_diag]    ;   dy_nondiag := dy_diag
                mov     [dy_nondiag],cx
                jmp     @@Init          ;end
        @@A_ge_B:                       ;else
                                        ;begin
                mov     cx,[dx_diag]    ;   dx_nondiag := dx_diag;
                mov     [dx_nondiag],cx
                mov     [dy_nondiag],0  ;   dy_nondiag := 0
                                        ;end;
        @@Init:
                add     bx,bx
                mov     [nondiag_inc],bx;nondiag_inc := b + b;     // set initial d increment values
                sub     bx,     ax
                mov     di,     bx      ;d := b + b - a;           // initial value for d is 2*b - a
                sub     bx,     ax      ;diag_inc    := b + b - a - a;
                mov     [diag_inc],     bx
        mov     cx,     ax              ;for i := 0 to a do
        inc     cx
        @@ForI:                         ;begin   /// draw the a+1 pixels
                push    cx
                mov     ah,     0Ch     ;   drawPixel (bitmap, x, y, color);
                mov     al,     byte ptr [Color]
                mov     bh,     0
                mov     cx,     si
                ;mov     dx,     dx
                int     10h
                cmp     di,     0       ;   if d < 0 then            // is midpoint above the line?
                jge     @@ByDiagonal    ;   begin                 // step nondiagonally
                        add     si,[dx_nondiag] ;      x := x + dx_nondiag;
                        add     dx,[dy_nondiag] ;      y := y + dy_nondiag;
                        add     di,[nondiag_inc];      d := d + nondiag_inc  // update decision variable
                        jmp     @@NextP ;   end
                @@ByDiagonal:           ;   else
                                        ;   begin                 // midpoint is above the line; step diagonally}
                        add     si,[dx_diag]    ;      x := x + dx_diag;
                        add     dx,[dy_diag]    ;      y := y + dy_diag;
                        add     di,[diag_inc]   ;      d := d + diag_inc
                @@NextP:                        ;   end;
                pop     cx
        loop    @@ForI                  ;end;
        ret
DrawLine        endp
 
end     main
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.12.2018, 17:56
Ответы с готовыми решениями:

Рисование линии при помощи мыши
Здравствуйте! Возникла следующая проблема и буду очень благодарна, если кто-нибудь сможет мне помочь. Необходимо заносить значение оси Х...

Рисование линии при помощи мыши
Добрый вечер. Есть код рисования линии по двум точкам (которые заданы в кач-ве переменных). Хочу эти переменные заполнять координатами...

Рисование линий от точки до точки при помощи мыши
Нашла задачу, рисует линии, как я поняла от точки до точки. С помощью tasm и tlink делаю exe файл, запускается, курсор видно, но линии не...

7
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8655 / 4490 / 1669
Регистрация: 01.02.2015
Сообщений: 13,898
Записей в блоге: 12
08.12.2018, 19:36
Спасибо за код.
0
0 / 0 / 0
Регистрация: 06.06.2018
Сообщений: 6
08.12.2018, 20:10  [ТС]
Нужно добавить функцию перемещения прямой, ну и чтоб она рисовалась параллельно одной из осей, у кого есть идеи, хэлпаните.
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8655 / 4490 / 1669
Регистрация: 01.02.2015
Сообщений: 13,898
Записей в блоге: 12
08.12.2018, 20:31
После определения координат отрезка уточнить, где приращение больше по горизонтали или вертикали - и после этого выбрать направление. Упростить процедуру рисования линии с алгоритма Брезенхэма до простой вертикальной или горизонтальной линии.

Это хорошая идея.
1
0 / 0 / 0
Регистрация: 06.06.2018
Сообщений: 6
08.12.2018, 21:05  [ТС]
Еще бы понять как это реализовать с точки зрения кода на ассемблере.
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8655 / 4490 / 1669
Регистрация: 01.02.2015
Сообщений: 13,898
Записей в блоге: 12
08.12.2018, 21:09
Это за вас у меня не получиться. Уж извините.

Могу посоветовать перечитать старые лабы по вычислению кусочных функций - вспомните о ветвлениях.
1
0 / 0 / 0
Регистрация: 06.06.2018
Сообщений: 6
14.12.2018, 20:35  [ТС]
Выравнивает только по оси Ox, как добавить сравнение приращений с осью Oy?
Код:
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
.model tiny  
org 100h 
.data
    x1 dw ?
    x2 dw ?
    y  dw ? 
    firstpos dw ?
    secondpos dw ?
    divconst dw 2h
    const dw 140h
.code
 
 
 
start:  
    mov ax,13h
    int 10h
    push 0A000h
    pop es  
    call GetDrawing
   
    
    
    X1Higer:
    mov ax,firstpos
    sub ax,secondpos
    mov cx,ax
   
    add ax,x1
    mov di,firstpos
    mov al,0Fh; öâåò ëèíèé    
   
    diminus:
        dec di
        dec di
        stosb
        loop diminus
       
    call GetDrawing
    retn;
    
    GetMouseClick:
    mov bx,1
    call GetMouseState
    and bx, 00000001b
    jz GetMouseClick
    ret
    
    GetMouseState:
    mov ax,3
    int 33h
    ret    
    
    
    
    GetDrawing:
    call GetMouseClick
    mov x1,cx
    mov cx,2h
    mov ax,x1 
    mov y, dx
    div cl
    mov x1,ax 
    
    mov ax, y
    mul const
    add ax,x1
    mov firstpos,ax
    call GetMouseClick
    mov x2,cx
    mov cx,2h
    mov ax,x2
    
    div cl
    mov x2,ax
    mov ax,y
    mul const
    add ax,x2
    mov secondpos,ax
    mov ax,secondpos
    cmp ax,firstpos
    jg X2Higher
    call X1Higer    
    
    X2Higher:
    mov ax,secondpos
    sub ax,firstpos
    mov cx,ax
    add ax,x1
    mov di,firstpos
    mov al,0Fh
    rep stosb
    ;int 16h
    ;mov ax,3
    ;int 10h
    call GetDrawing
    retn
    
end start
0
0 / 0 / 0
Регистрация: 06.06.2018
Сообщений: 6
16.12.2018, 18:37  [ТС]
Разобрался, тема закрыта :3
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.12.2018, 18:37
Помогаю со студенческими работами здесь

Рисование линии в PictureBox при помощи мыши
Как организовать такую программку: На форме есть picturebox, необходимо мышкой на нем нарисовать произвольную линию. Как это сделать?

Рисование осей координат
Как нарисовать оси координат? и как изменить нуль этой оси? (а то в PictureBox нуль в левом верхнем углу, а мне нужно в левом нижнем и...

Рисование осей координат
Нужна помощь, у нас в распоряжении имеется код, который рисует ось Ох. Нужно дописать код, чтобы он рисовал еще и ось Оу. Выполняется все в...

Вычислить площадь треугольника, образованного пересечением осей координат и прямой
Написать программу в Visual Basic (Консольное приложение) Вычислить s треугольника,образованного пересечением осей координат и прямой...

Найти площадь треугольника, который отсекается от осей координат прямой:
2х+7у-140=0


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru