Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рисование линии по двум точкам 
:(
    Опции темы
65tg
  Дата 23.6.2008, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Нужна помощь. На 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


Или другие способы нарисовать линию

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  prim_EXE.ASM 3,57 Kb
PM MAIL   Вверх
Mikl_
  Дата 26.6.2008, 09:28 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



65tg, Посмотрел твой код -- одна сплошная ошибка, чтобы не перечислять, попробую показать, как рисуется линия горизонтальная, вертикальная и две диагональные, если поймешь, то и с алгоритмом Брезенхайма разберешься smile 
Код
.286
.model tiny
.code
org 100h
start:    MOV AH,0Fh        ;запомнить видеорежим
    INT 10h
    MOV VIDEOR,AX
    mov ax,13h
    int 10h
    PUSH 0A000h
    POP ES; позиционируем ES на область видеопамяти
    MOV DI,X  ; в DI координаты начальной точки по X
    MOV AX,320; длина строки экрана
    MUL Y; умножаем на Y
    ADD DI,AX; и складываем с X
    MOV AL,COLOR; цвет линии
; рисуем горизонтальную линию
    MOV CX,N; длина линии
    REP STOSB
;Вертикальную линию обычно рисуют циклом
    MOV CX,N; длина линии
A1:    MOV ES:[DI],AL; рисуем точку на строке
    ADD DI,320; переход на следующую строку
    LOOP A1
;диагональную линию с наклоном влево можно нарисовать циклом
    MOV CX,N; длина линии
A2:    MOV ES:[DI],AL; рисуем точку на строке
    ADD DI,319; переход на следующую строку
    LOOP A2
;диагональную линию с наклоном вправо - циклом
    MOV CX,N; длина линии
A3:    MOV ES:[DI],AL; рисуем точку на строке
    ADD DI,321; переход на следующую строку
    LOOP A3
    MOV AH,0    ;ждем нажатия на любую клавишу
    INT 16h
EXIT:    MOV AX,VIDEOR
    INT 10h    ;восстанавливаем видеорежим 
    RET        ;и выходим из программы
VIDEOR    dw 0
X dw 0
Y dw 0
N dw 100
COLOR db 0Fh
end start

для компиляции использую 
Код
tasm a.asm   >0.txt
tlink a.obj /t     >1.txt


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

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

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


 




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


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

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