Нужна помощь. На tasm необходимо между двумя точками с координатами x,y нарисовать линию. Пробовал сделать с помощью алгортма Брезенхэма. Но имеющийся код вместо желаемого результата, заполняет постепенно весь экран точками. Может кто укажет на ошибку в коде.
| Код | stack_seg_name segment dw 128 dup (?)
stack_seg_name ends
data_seg_name segment START_X DW 10 END_X DW 50 START_Y DW 10 END_Y DW 100 COLOR DB 2 DIAGONAL_Y_INCREMENT DW ? DIAGONAL_X_INCREMENT DW ? SHORT_DISTANCE DW ? STRAIGHT_X_INCREMENT DW ? STRAIGHT_Y_INCREMENT DW ? STRAIGHT_COUNT DW ? DIAGONAL_COUNT DW ?
data_seg_name ends
code_seg_name segment assume ss:stack_seg_name, ds:data_seg_name, cs:code_seg_name
startpoint:
;---установка режима дисплея MOV AX,0 ;функция установки режима MOV AL,10h ;цветной 320*200 INT 10H ;установка режима ;---установка начальных инкрементов для каждой позиции точки MOV CX,1 ;инкремент для оси x MOV DX,1 ;инкремент для оси y ;---вычисление вертикальной дистанции MOV DI,END_Y ;вычитаем координату начальной SUB DI,START_Y ;точки из координаты конечной JGE KEEP_Y ;вперед если наклон < 0 NEG DX ;иначе инкремент равен -1 NEG DI ;а дистанция должна быть > 0 KEEP_Y: MOV DIAGONAL_Y_INCREMENT,DX ;---вычисление горизонтальной дистанции MOV SI,END_X ;вычитаем координату начальной SUB SI,START_X ;точки из координаты конечной JGE KEEP_X ;вперед если наклон < 0 NEG CX ;иначе инкремент равен -1 NEG SI ;а дистанция должна быть > 0 KEEP_X: MOV DIAGONAL_Y_INCREMENT,CX ;---определяем горизонтальны или вертикальны прямые сегменты CMP SI,DI ;горизонтальные длиннее? JGE HORZ_SEG ;если да, то вперед MOV CX,0 ;иначе для прямых x не меняется XCHG SI,DI ;помещаем большее в CX JMP SAVE_VALUES;сохраняем значения HORZ_SEG: MOV DX,0 ;теперь для прямых не меняется y SAVE_VALUES: MOV SHORT_DISTANCE,DI ;меньшее расстояние MOV STRAIGHT_X_INCREMENT,CX ;один из них 0, MOV STRAIGHT_Y_INCREMENT,DX ;а другой - 1. ;---вычисляем выравнивающий фактор MOV AX,SHORT_DISTANCE ;меньшее расстояние в AX SHL AX,1 ;удваиваем его MOV STRAIGHT_COUNT,AX ;запоминаем его SUB AX,SI ;2*меньшее - большее MOV BX,AX ;запоминаем как счетчик цикла SUB AX,SI ;2*меньшее - 2*большее MOV DIAGONAL_COUNT,AX ;запоминаем ;---подготовка к выводу линии MOV CX,START_X ;начальная координата x MOV DX,START_Y ;начальная координата y INC SI ;прибавляем 1 для конца MOV AL,COLOR ;берем код цвета ;---теперь выводим линию MAINLOOP: DEC SI ;счетчик для большего расстояния JZ LINE_FINISHED ;выход после последней точки MOV AH,12 ;функция вывода точки INT 10H ;выводим точку CMP BX,0 ;если BX < 0, то прямой сегмент JGE DIAGONAL_LINE ;иначе диагональный сегмент ;---выводим прямые сегменты ADD CX,STRAIGHT_X_INCREMENT ;определяем инкре- ADD DX,STRAIGHT_Y_INCREMENT ;менты по осям ADD BX,STRAIGHT_COUNT ;фактор выравнивания JMP SHORT MAINLOOP ;на следующую точку ;---выводим диагональные сегменты DIAGONAL_LINE: ADD CX,DIAGONAL_X_INCREMENT ;определяем инкре- ADD DX,DIAGONAL_Y_INCREMENT ;менты по осям ADD BX,DIAGONAL_COUNT ;фактор выравнивания JMP SHORT MAINLOOP ;на следующую точку LINE_FINISHED:
code_seg_name ends end startpoint
|
Или другие способы нарисовать линию |