1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

Нарисовать эллипс

Тема в разделе "WASM.DOS/BIOS/Vesa/ports", создана пользователем dessaber, 20 ноя 2011.

  1. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    Здравствуйте, дорогие люди. Дали задание - нарисовать эллипс. Придумал я рисовать так - вспомнил уравнение эллипса; возьму Y, к примеру, за -B; Х - за -A; буду наращивать Х до тех пор, пока ((X^2)/(A^2))+((Y^2)/B^2)) не равно 1; как только равно - нарисовал четыре точки: (Х, Y), (-X,Y), (-X,-Y), (X,-Y); скинул Х, нарастил Y и т.д. Вот до куда дошел:
    Код (ASM):
    1. .model small
    2. .stack 100h
    3. .data
    4. message1 db 0ah,0dh,'Enter A : $'
    5. message2 db 0ah,0dh,'Enter B : $'
    6. message3 db 0ah,0dh,'Press <R> to repeat...$'
    7. x db 0
    8. y db 0
    9. a db 0
    10. b db 0
    11. form db 0 ;((x^2)/(a^2))+((y^2)/(b^2))
    12. .code
    13. mov ax,@data
    14. mov ds,ax
    15. xor ax,ax
    16. ;----------------------A-INPUTIN-------------------------
    17. mov ah,9 ;function for a string inputin
    18. mov dx, offset message1 ;sendin the string to dx
    19. int 21h ;callin an interception
    20. mov ah, 1 ;function for a symbol inputin
    21. int 21h
    22. sub al,30h
    23. mov a,al
    24. ;---------------------B-INPUTIN--------------------------
    25. xor al,al
    26. mov ah,9
    27. mov dx, offset message2
    28. int 21h
    29. mov ah, 1
    30. int 21h
    31. sub al,30h
    32. mov b,al
    33. ;---------------------------------------------------------------
    34. mov cl,a ;sendin A to CL
    35. mov x,cl ;sendin CL to X
    36. neg x ;makin X equal to -A
    37. xor cl,cl
    38.  
    39. mov cl,b
    40. mov y,cl
    41. neg y ;makin Y equal to -B
    42. xor cl,cl
    43. computin:  
    44. mov al,x ;sendin X to AL
    45. mul x ;makin AХ equal to X^2
    46. div a
    47.  
    48. xor ax,ax
    49. mov ax,4c00h
    50. int 21h
    51. END
    После ввода числа B окошко закрывается сразу. По регистрам прогнал - divide by zero. По переменным прогнал - вроде все на месте,у А конкретное значение, не нуль. В чем косяк?
     
    Последнее редактирование модератором: 24 дек 2016
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.398
    Адрес:
    Fryazino
    Незнание команды div. Открой учебник или справочник посмотри, какие регистры на входе этой команды и какие на выходе. Ну если кратко, то не все регистры инициированы верно.
     
  3. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    оО.
    Здесь? Т.е. частное слишком велико? Мой вариант - это №2?
     
  4. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    Когда то реализовывал алгоритм Брезенхэма на тасме используя функции биос для рисования эллипса, если найду то скину. В любом случае посмотрите данный алгоритм, в сети полно примеров его реализации на разных языках
     
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.992
    dessaber
    Для начала нарисуй эллипс с уже известными А и В -- сможешь -- следующим шагом будет вывод эллипса с заданными пользователем А и В.

    Ниже программа, которая выводит окружность, т.е. A=B=R
    У окружности координаты любой точки относительно ее центра вычисляются из соотношения R²=X²+Y², где R радиус окружности. С точки зрения программирования достаточно нарисовать 1/8 часть окружности, остальное сделает симметрия. Функция ЯВУ CIRCLE строит окружность либо, вычисляя синус, либо, двигаясь например по оси X, вычисляет на каждом шаге координату Y по формуле √[o]R²− X²[/o]. Для вычисления квадратного корня или функции синуса пришлось бы использовать сопроцессор, а работать с FPU dessaber вряд ли умеет. Поэтому рисуем окружность используя только целочисленную арифметику, да и на экране можно выводить точку только туда, где находится люминофор, а не между люминофорами. Пусть центр окружности находится в точке (0, 0) Y=R=100 и X=0 по формуле Y² равен R²−X². По мере движения по оси X мы должны выяснить, когда нам необходимо уменьшить Y. Это нужно сделать если отклонение от Y будет больше 0,5 величины люминофора, т.е. больше должна засвечиваться соседняя точка. Вычисляем квадрат отклонения: (Y−0,5)²=Y²−Y+0,25. Выражение Y²−Y вычисляется в целых числах, а 0,25 игнорируем. Если разность R²−X² больше чем Y²−Y необходимо уменьшить Y на единицу и опять пересчитать ту величину, когда необходимо будет снова изменить Y и так в цикле. Выводим N точек, где N вычисляется из значения L=2*pi*R. Так как нужно нарисовать 1/8 окружности N=L/8=pi*R/4≈157*R/200. При изменении строки radius equ ХХ все остальные константы пересчитаются автоматически
    Код (Text):
    1. ; masm dos com #
    2. .286
    3. .model tiny
    4. .code
    5. org 100h
    6. radius equ 99 ;рисуем окружность с радиусом 99
    7. radius2 equ radius*radius ;квадрат радиуса
    8. diametr equ radius*2 ;диаметр окружности
    9. n equ 157*radius/200;количество точек на 1/8
    10. color equ 10 ;цвет окружности
    11. start:  mov ah,0Fh  ;узнать номер текущего видеорежима
    12.     int 10h
    13.     mov videor,al ;запомним текущий видеорежим
    14.     mov ax,13h;установить видеорежим 320х200х256
    15.     int 10h
    16.     push 0A000h;установить регистр es на сегмент
    17.     pop es ; видеопамяти
    18.     xor bp,bp ;будем увеличивать x и y
    19.     mov y,radius-1 ;координаты x=0 и y=r
    20.     call draw_oct1 ;рисуем восьмушку окружности
    21.     mov bp,radius-1 ;координата x=2*r
    22.     mov y,0 ;координата y=0
    23.     call draw_oct2 ;рисуем восьмушку окружности
    24.     neg delta_x ;увеличиваем y и уменьшаем x
    25.     mov y,radius  
    26.     mov bp,diametr ;координаты y=r и x=2*r
    27.     call draw_oct1 ;рисуем восьмушку окружности
    28.     mov bp,radius ;координата x=r
    29.     mov y,0 ;координата y=0
    30.     call draw_oct2 ;рисуем восьмушку окружности
    31.     neg delta_y ;уменьшаем координаты y и x
    32.     mov y,radius ;координата y=r
    33.     mov bp,diametr ;координата x=2*r
    34.     call draw_oct1 ;рисуем восьмушку окружности
    35.     mov bp,radius ;координата x=r
    36.     mov y,diametr ;координата y=2*r
    37.     call draw_oct2 ;рисуем восьмушку окружности
    38.     neg delta_x ; уменьшаем y и увеличиваем x
    39.     xor bp,bp ;координата x=0
    40.     mov y,radius ;координата y=r
    41.     call draw_oct1 ;рисуем восьмушку окружности
    42.     mov bp,radius ;координата x=r
    43.     mov y,diametr ;координата y=2*r
    44.     call draw_oct2 ;рисуем восьмушку окружности
    45.     xor ax,ax  ;ожидание нажатия любой клавиши
    46.     int 16h
    47.     mov ax,word ptr videor;восстановление видеорежима
    48.     int 10h
    49.     ret  ;выход из программы
    50. delta_calc proc;рассчитаем ошибку накопления
    51.     mov bx,ax ;в ax значение координаты x или y
    52.     dec ax ;вычислим (y+0,5)² ≈ y²+y
    53.     mul ax ;или (x+0,5)² ≈ x²+x
    54.     add ax,bx
    55.     mov delta,ax ;и поместим это значение в delta
    56.     retn
    57. delta_calc endp
    58. ;процедура прорисовки 1/8 окружности с вычислением
    59. draw_oct1 proc; координаты x
    60.     imul di,y,320; di=y*320
    61.     mov ax,bp  
    62.     sub ax,radius ;bp=x ax=r-x
    63.     call delta_calc ;расчет ошибки накопления по x
    64.     mov cx,n
    65. circ1: mov ax,y
    66.     sub ax,radius ;ax=y-r
    67.     mul ax
    68.     neg ax
    69.     add ax,radius2 ;ax=r²-y²
    70.     cmp delta,ax ;сравнить текущий x²=r²-y² с ошибкой
    71.     jbe a3 ;накопления, если меньше, увеличиваем или
    72.     add bp,delta_x;уменьшаем только y, иначе
    73.     mov ax,bp;увеличиваем или уменьшаем еще и x и
    74.     sub ax,radius; вычисляем новую ошибку накопления
    75.     call delta_calc
    76. a3: cmp delta_y,1
    77.     jne a1
    78.     add di,320
    79.     jmp short a2
    80. a1: sub di,320
    81. a2: mov byte ptr es:[di][bp],color;выводим точку на
    82.     mov ax,delta_y; экран
    83.     add y,ax
    84.     loop circ1  ;повторяем цикл
    85.     retn
    86. draw_oct1 endp
    87. ;процедура прорисовки 1/8 окружности с вычислением
    88. draw_oct2 proc; координаты x
    89.     imul di,y,320; di=y*320
    90.     mov ax, y
    91.     sub ax,radius
    92.     call delta_calc
    93.     mov cx,n
    94. circ2:  mov ax,bp
    95.     sub ax,radius
    96.     mul ax
    97.     neg ax
    98.     add ax,radius2 ;ax=r²-(x-r)²
    99.     cmp delta,ax
    100.     jbe a5
    101.     mov ax,delta_y
    102.     add y,ax
    103.     mov ax,y
    104.     sub ax,radius
    105.     call delta_calc
    106.     cmp delta_y,1
    107.     jne a4
    108.     add di,320
    109.     jmp short a5
    110. a4: sub di,320
    111. a5: add bp,delta_x
    112.     mov byte ptr es:[di][bp],color
    113.     loop circ2
    114.     retn
    115. draw_oct2 endp
    116. videor db 0,0  ;значение текущего видеорежима
    117. delta dw  0 ;ошибка накопления
    118. delta_x dw  1 ;смещение по оси x
    119. delta_y dw  1 ;смещение по оси y
    120. y  dw  0 ;координата y
    121. end start
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.992
    Для рисования эллипса, также как и для рисования окружности, рисуют четыре октанта, в которых основной осью является X, а затем четыре октанта с основной осью Y. Также как и в предыдущей программе двигаемся по основной оси на 1 точку с каждым шагом вычисляя при этом смещение по неосновной оси. Разница в методе определения необходимости передвижения по неосновной оси. Уравнение эллипса X²/A²+Y²/B²=1 или B²X²+A²Y²–A²B²=0 Прежде чем приступить к рисованию дуги, для которой основная ось X, решаем уравнение для X=0 и Y=B–0,5 что позволяет оценить, как далеко X от того значения при котором (Y=B–0,5) – точка перехода на следующий пиксель по оси Y. Потом пересчитаем уравнение для X+1 и т. д. Когда результат станет положительным – уменьшаем координату текущей точки по неосновной оси и подогняем уравнение под новое значение Y. Проделываем это до конца дуги. Подставляем X=0 и Y=B–0,5 в уравнение эллипса B²∙0+A²(B–0,5)²–A²B²=0 A²(B–0,5)²–A²B²=A²B²–A²B+0,25∙A²–A²B²=0,25∙A²–A²B или 0,25∙A²–A²B=0 начальная ошибка накопления равна 0,25∙A²–A²B, используем целочисленную арифметику и игнорируем 0,25∙A²
    Вычисленную ошибку накопления необходимо корректировать с каждым шагом по оси X, пока она не станет положительной, указывая нам изменить Y. Для ошибки накопления в текущей точке слагаемое с X выглядит как B²X², при переходе на следующую точку B²(X+1)²= B²X²+ 2B²X+B² значение B²X² уже содержится в текущей ошибке накопления, поэтому значение 2B²X+B² добавляется к X-составляющей при каждом шаге по оси X. Когда ошибка накопления превысила или равна 0, делается шаг по оси Y и пересчитывается ошибка накопления для следующего шага. Для этого вместо Y в уравнение эллипса подставляется (Y–1), поэтому слагаемое с Y выглядит следующим образом A²(Y–1)²=A²Y² – 2A²Y+A² поскольку A²Y² у нас уже есть, то увеличиваемая часть уравнения (–2A²Y+A²) что легко вычисляется в целых числах
    Рисование прекращается по достижении наклона касательной в 45º. Сигнал к этому – одинаковое или большее требуемое приращение по неосновной оси, чем по основной.
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.992
    Код (Text):
    1. ; masm dos com #
    2. .286
    3. .model tiny
    4. .code
    5. org 100h
    6. color equ 10; цвет точки
    7. a equ 40; сюда подставляем радиус А
    8. b equ 50; а сюда -- радиус В
    9. start:  mov ah,0Fh  ;узнать номер текущего видеорежима
    10.     int 10h
    11.     mov videor,al ;запомним текущий видеорежим
    12.     mov ax,13h;установить видеорежим 320х200х256
    13.     int 10h
    14.     push 0A000h;установить регистр es на сегмент
    15.     pop es ; видеопамяти
    16.     mov cx,a*2+1
    17.     finit
    18. a3: fild x; вычисляем значение Y из уравнения эллипса
    19.     fld st
    20.     fmulp st(1),st
    21.     fidiv a2
    22.     fld1
    23.     fsubrp st(1),st
    24.     fsqrt
    25.     fimul b1
    26.     fistp y
    27.     imul di,y,320; координату Y на разрешение по вертикали
    28.     mov bp,x
    29.     inc x; переходим к следующей точке
    30.     mov byte ptr es:[di][bp][32160],color; вывод точки на экран
    31.     neg di; рисуем симметричную точку
    32.     mov byte ptr es:[di][bp][32160],color; вывод точки на экран
    33.     loop a3
    34.     xor ax,ax  ;ожидание нажатия любой клавиши
    35.     int 16h
    36.     mov ax,word ptr videor;восстановление видеорежима
    37.     int 10h
    38.     ret  ;выход из программы
    39. videor db 0,0  ;значение текущего видеорежима
    40. y dw ? ;координата y
    41. x dw -a;координата Х
    42. a2 dw a*a; квадрат радиуса А
    43. b2 dw b*b; квадрат радиуса В
    44. b1 dw b; радиус B
    45. a1 dw a; радиус А
    46. end start
     
  8. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    Mikl___ спасибо канеш за алгоритм, но в чем проблема в моем коде? Рано или поздно мне эту проблему придется решать в независимости от того, каким образом я эллипс рисовать буду. Что, у меня X^2 32 бита, а А - 8? Или X^2 16 бит и А тоже 16? Если так, то проблему решать с помощью CBW, CWDE, CWD, CDQ?
     
  9. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.992
    dessaber
    Проблема в том, что ты начал решать ее не с того конца, научись сперва рисовать, а передача параметров вторична, я нарисовал тебе эллипс в режиме 13h (320х200х256) а для другого графического режима всё будет по другому
     
  10. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    Mikl___, причем здесь вообще видеорежим? Вот уж действительно до чего еще как до Нью-Йорка пехом. Ты если не знаешь так и скажи, а то вот то да потому...
     
  11. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    dessaber
    А так все начиналось ... ))
     
  12. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    dessaber
    Если осуществлять прямую запись в видеопамять, то очень даже причем. А если рисовать с помощью видеосервиса биос(int 10h), то думаю да, особого значения не имеет(хотя конечно при таком раскладе иногда вместо эллипса может получиться круг:dntknw:)
     
  13. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    _sheva740, pashe4ka13, боюсь вы меня просто не правильно поняли. Да, ок, видеорежим, алгоритм Брезенхема и т.д. это все очень хорошо, полезно, отдельное за это спасибо. Но передо мной стоит конкретная задача - написать программу рисования эллипса с вводимыми пользователем данными. Заниматься этим придется все равно. Pavia совершил попытку указать мне на ошибку в уже написанном мной коде. Я вопрошаю во втором посте, правильно ли я его понял, вполне, мой взгляд, справедливо полагая, что кто-то из других форумчан его почин далее подхватит и ответит мне, мол, да, чувачок, с div'oм ты косякнул и т.д.
    И даже если предположить, что возможно исхитриться и взять, к примеру, код Mikl___'а и чисто добавить в него ввод, обойдя, не знаю как, этот div. Пробел у меня по этому аспекту останется все равно.
     
  14. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    У тебя там переменная а это делитель, она размером в байт. Делимое при этом может быть размером в слово dw и должно находиться в аккумуляторе. После деления в AL частное, а в AH остаток. Ты делишь слово на байт. Твой вариант это-№1
     
  15. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    pashe4ka13, ок, спс биг

    ЗЫ Брезенхема на тасме не нашел?
     
  16. pashe4ka13

    pashe4ka13 New Member

    Публикаций:
    0
    Регистрация:
    4 окт 2010
    Сообщения:
    263
    К сожалению не могу найти, но в сети полно примеров его реализации на различных языках. Могу лишь посоветовать для его реализации использовать математический сопроцессор и функцию 0ch по программному прерыванию int 10h. Да и еще где-то я видел сайт, где рисование кругов и эллипсов приведено на различных уровнях. Высокий BASIC: CIRCLE , низкий реализация оператора CIRCLE на ассемблере, правда для какого проца я не помню, как бы не под ZX-80. Но главное там хорошо расписан был сам алгоритм.
     
  17. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.992
    Хамить-то, зачем? Рисование эллипса задача не тривиальная, судя по вопросу о видеорежимах, ты о них не знаешь и вряд ли способен вывести на экран даже точку заданного цвета... В #7 готовая программа для вывода эллипса
    то что касается твоего кода
    Код (Text):
    1. mov al,x ;sendin X to AL
    2. mul x ;makin AХ equal to X^2
    3. div a
    ошибка в следующем – после возведения Х в квадрат, перед делением на А значение в регистре АН у тебя оказалось больше, чем значение А и частное оказалось слишком велико для его размещения в регистре al. Отсюда и метод лечения –> определить размер А как WORD и между mul x и div a вставь xor dx,dx

    Увеличиваю скорость выведения эллипса на экран
    Число 32160 – это координата центра эллипса = разрешение по горизонтали (=320) * половину разрешения по вертикали (=200/2) + половина разрешения по горизонтали (=320/2) предназначено только для графического режима 13h (320x200x8)

    из уравнения эллипса следует, что ось абсцис эллипс пересекает в точках (b, 0) и (–b, 0), а ось ординат в точках (0, a) и (0,–a). Эти четыре точки называются вершинами эллипса. Для получения координат этих точек расчет Y через квадратный корень не нужен, кроме того, удаляю команду fld1 из тела цикла и, используя симметрию, вывожу сразу по 4 точки
    Код (Text):
    1. ; masm dos com #
    2. .286p
    3. .model tiny
    4. color equ 10
    5. a equ 99
    6. b equ 63
    7. .code
    8. org 100h
    9. start:  mov ax,13h
    10.     int 10h
    11.     push 0A000h
    12.     pop es
    13.     finit
    14.     mov al,color
    15.     mov bp,x
    16.     mov es:[bp+32160],al; X=–b Y=0
    17.     neg bp
    18.     mov es:[bp+32160],al; X=b Y=0
    19.     imul di,a1,320
    20.     mov es:[di+32160],al; X=0  Y=a
    21.     neg di
    22.     mov es:[di+32160],al; X=0  Y=–a
    23.     mov cx,b-1
    24.     fld1
    25. @@: inc x
    26.     fild x
    27.     fld st
    28.     fmulp st(1),st; st(0)=x*x
    29.     fidiv b2      ; st(0)=-x²/b² st(1)=1
    30.     fadd st,st(1) ; st(0)=1-x²/b²
    31.     fsqrt         ; st(0)=√(1-x²/b²)
    32.     fimul a1      ; st(0)=a*√(1-x²/b²)
    33.     fistp y
    34.     mov bp,x
    35.     imul di,y,320
    36.     mov es:[bp+32160][di],al; X  Y
    37.     neg di
    38.     mov es:[bp+32160][di],al; X –Y
    39.     neg bp
    40.     mov es:[bp+32160][di],al;–X –Y
    41.     neg di
    42.     mov es:[bp+32160][di],al;–X  Y
    43.     loop @b
    44.     mov ah,0
    45.     int 16h
    46.     mov ax,3
    47.     int 10h
    48.     retn
    49. x  dw -b
    50. y  dw ?
    51. b2 dw -b*b
    52. a1 dw a
    53. end start
    Алгоритм Брезенхема для построения эллипса без лишней воды как раз и описан в #6 но ведь читать ты не хочешь...
     
  18. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    Mikl___, ну так если обидел, то извини. Просто вопрошал я много раз, а ответить на мой вопрос никому особо не хочется. Пардон за несдержанность. Вопрос, который ты имеешь ввиду, equ не "Ой, а чевось это такое-то?", а "До этого дойти еще успеем".

    Кроме того, я тебе не то что точку, я тебе аж целый прямоугольник могу вывести.
    Код (Text):
    1. .model small
    2. .stack 100h
    3. .data
    4. x dw 50
    5. y dw 50
    6. .code
    7. start:
    8. mov ax,@data
    9. mov ds,ax
    10. mov AX, 13h
    11. int 10h
    12.  
    13. asd:
    14. mov AH, 0Ch
    15. mov AL, 7
    16. mov CX, x
    17. mov DX, y
    18. inc x
    19. int 10h
    20. cmp CX, 150
    21. jne asd
    22.  
    23. asd_1:
    24. mov AH, 0Ch
    25. mov AL, 7
    26. mov CX, x
    27. mov DX, y
    28. inc y
    29. int 10h
    30. cmp DX, 180
    31. jne asd_1
    32.  
    33. asd_2:
    34. mov AH, 0Ch
    35. mov AL, 7
    36. mov CX, x
    37. mov DX, y
    38. dec x
    39. int 10h
    40. cmp CX, 50
    41. jne asd_2
    42.  
    43. asd_3:
    44. mov AH, 0Ch
    45. mov AL, 7
    46. mov CX, x
    47. mov DX, y
    48. dec y
    49. int 10h
    50. cmp DX, 50
    51. jne asd_3
    52.  
    53. mov ax,4c00h
    54. int 21h
    55. end start
    о как
     
  19. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.992
    dessaber
    Ну вот и добрались до сути
    Код (Text):
    1. mov AX, 13h
    2. int 10h
    как раз и устанавливает режим 320 точек на 200 точек 256 возможных цветов,
    Код (Text):
    1. mov AX, 12h
    2. int 10h
    установит графический режим 640 х 480 16 возможных цветов и т.д. и количество этих режимов -- легион, не зная параметров графического режима ты не сможешь сразу написать программу по выводу этого прямоугольника в центр экрана и тебе придется действовать подбором. При выходе из твоей программы ты должен был восстановить видеорежим, который был до вызова этой программы, иначе пользователю придется смотреть на твой квадрат и рябь вверху экрана, а потом жать на Ctrl+Alt+Del. Выводить фигуры по-точечно через 0Ch функцию 10h прерывания, особенно, если это касается графики меняющейся несколько раз в секунду – непозволительно долго, поэтому пишут напрямую в видеопамять не используя 10h прерывание...
    Ввод радиусов через
    Код (Text):
    1. mov ah, 1 ;function for a symbol inputin
    2. int 21h
    3. sub al,30h
    4. mov a,al
    ограничивает тебя числами от 0 до 9, в моей программе радиусы ограничены параметром видеорежимов, то есть максимум по горизонтали для 13h режима 160, а по вертикали 100. Есть еще несколько вопросов:
    1) как ты собрался вычислять квадратный корень? Ведь из уравнения эллипса
    [math]X^2/A^2+Y^2/B^2=1[/math] и [math]Y=B\sqrt{1-X^{2}/A^{2}}[/math]
    2) для нормального эллипса значение X²/A² плавно меняется от 0 до единицы, а в целочисленных расчетах у тебя пока –А<X<A X²/A²=0, а потом (при X>A) вдруг резко станет больше единицы, поэтому вместо эллипса у тебя будет полоска, не удивляйся этому...
    3) только что пришло в голову, чтобы не заморачиваться с квадратами можно
    [math]Y=B\sqrt{1-X^{2}/A^{2}}[/math] представить как [math]Y=B/A\sqrt{(А–X)(A+Х)}[/math]
    4) Для общего развития почитай это
     
  20. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    Mikl___
    1), 3) А зачем мне вычислять квадратный корень? Просто подбор от -А до А для Х и от -В до В для Y. Как только левая часть канонического уравнения эллипса равна 1, то рисуем.
    2) Если будет больше 1 хотя бы только X²/A², то он ничего не будет рисовать.
    4) спс