Board.KolibriOS.org
http://board.kolibrios.org/

Начинающий
http://board.kolibrios.org/viewtopic.php?f=2&t=1082
Page 5 of 12

Author:  Mario [ Fri Sep 04, 2009 12:59 am ]
Post subject:  Re: Начинающий

Относительно давно, когда я реализовывал на Фокале (на БК-0010) рисование окружности (функции не было, рисовал сначала точками, потом отрезками), в ходе экспериментов выяснил что при рисовании отрезками достаточно шага:
I = sqrt (R), (квадратный корень радиуса)
Соответственно окружность радиусом 50 состоит из 2Pi * R / I = 44 отрезков (с округлением 45, потому что окружность должна быть замкнута).
R100 = 63
R75 = 54
R50 = 45
R30 = 35
R10 = 19
R5 = 14
Конечно окружность получается немного угловатой, но думаю это можно использовать как базу. Например во Flash в родном плеере можно выбрать три уровня плавности отрисовки.
Как преимущество достаточно высокая скорость.

В твоем случае придется разбивать кривую на отрезки и вычислять для каждого отрезка свой радиус.

Author:  tsdima [ Fri Sep 04, 2009 10:50 am ]
Post subject:  Re: Начинающий

Кстати, я был немало удивлён, когда увидел вот такой простой алгоритм вычёрчивания окружности:
Code:
Private Sub Circ(x As Integer, y As Integer, r As Integer)
    Dim i As Integer, px As Double, py As Double
    px = 0: py = r
    For i = 0 To r * 3.1415926 * 2
        PSet (px + x, y - py), vbBlack
        px = px + py / r
        py = py - px / r
    Next
End Sub

Author:  Leency [ Fri Sep 04, 2009 12:42 pm ]
Post subject:  Re: Начинающий

А что означает строка "px = 0: py = r"?
На Си это будет выглядеть просто
px = 0; py = r;
?

Author:  Albom [ Fri Sep 04, 2009 12:50 pm ]
Post subject:  Re: Начинающий

да, именно так и будет выглядеть.

Author:  Leency [ Fri Sep 04, 2009 1:22 pm ]
Post subject:  Re: Начинающий

tsdima
Действительно работает.
Code:
void DrawCircle(int x, y, r)
{
   int i; float px=0, py=r, ii = r * 3.1415926 * 2;
   for (i = 0; i < ii; i++)
   {
        PutPixel(px + x, y - py, 0);
        px = py / r + px;
        py = -px / r + py;
   }
}


Attachments:
circle.kex [1.16 KiB]
Downloaded 131 times

Author:  Mario [ Fri Sep 04, 2009 2:01 pm ]
Post subject:  Re: Начинающий

Есть у метода один небольшой минус - в некоторых участках толщина линии не 1 пиксел, а 2.
Я правда не знаю может быть при рисовании отрезками тоже апроксимация может выдать такой финт ушами, а может и нет - надо проверять. Однако отсуствие Sin и Cos видимо значительно ускоряют отрисовку.

Только мне вот нифига не понятно зачем программе 1 Мб памяти? Уж Kfar насколько более сложная программа, но со всеми данными при запуске сожрал только чуть более 600 Кб...
Неужели нельзя в Си как в Fasm сделать вычисление размера при компиляции?

Author:  Leency [ Fri Sep 04, 2009 3:53 pm ]
Post subject:  Re: Начинающий

Mario
Думаю, можно. Не секрет, что я плохой программист, но на безрыбье и рак рыба.
Есть вот такая структура в kolibri.h--
Code:
char   os_name[8]   = {'M','E','N','U','E','T','0','1'};
dword  os_version   = 0x00000001;
dword  start_addr   = #main;
dword  final_addr   = #stop+32;
dword  alloc_mem    = 0x00100000;
dword  x86esp_reg   = 0x00100000;
dword  I_Param      = #param;
dword  I_Icon       = 0x0;
char param[256]="";
Я поставил
Code:
dword  alloc_mem    = #stop+1032;//0x00100000;
dword  x86esp_reg   = #stop+1032;//0x00100000;

Вроде работает, для circle, но тот же HTMLv отказывается работать с такими значениями. Наверное, именно в них вся загвоздка.

Attachments:
circle.kex [942 Bytes]
Downloaded 133 times

Author:  Mario [ Fri Sep 04, 2009 6:34 pm ]
Post subject:  Re: Начинающий

Вот так гораздо лучше - теперь код занимает только 4 Кб (минимальный размер страницы памяти).
Quote:
но тот же HTMLv отказывается работать с такими значениями. Наверное, именно в них вся загвоздка.

Есть 2 предположения:
1) Какойто участок твоего собственного кода портит область стека.
2) Размер стека недостаточен - попробуй 4096 или больше.

Кстати лучше немного увеличить:
dword menu_stak[100]=0;
Любой стек лучше брать с запасом, неизвестно насколько разрастется проект.

Author:  tsdima [ Fri Sep 04, 2009 9:19 pm ]
Post subject:  Re: Начинающий

Mario wrote:
Есть у метода один небольшой минус - в некоторых участках толщина линии не 1 пиксел, а 2.
Я правда не знаю может быть при рисовании отрезками тоже апроксимация может выдать такой финт ушами, а может и нет - надо проверять.

Стандартный алгоритм Брезенхема для линии не делает "такой финт ушами". Можно в вышеописанном алгоритме запоминать координаты двух последних точек, и если три точки стоят рядом, то предпоследнюю не рисовать. Во всяком случае это будет быстрее чем синус.

Author:  Mario [ Fri Sep 04, 2009 9:27 pm ]
Post subject:  Re: Начинающий

Ну, так ведь я и не спорил насчет производительности (почитай мой слова повнимательней), а если есть способ улучшить алгоритм, то замечательно.

Author:  Андрей Михайлович [ Mon Jul 19, 2010 10:40 am ]
Post subject:  Re: Начинающий

Приветствую! Дабы не создавать новую тему, спрошу здесь.

Задача:
Вывести число из переменной mistakes

Код:
Code:
draw_integer:   
   mov eax, 47
   mov ebx, 00000000000000000001000000000000b
   mov ecx, [mistakes]
   mov edx, 70*65536+25
   mov esi, 0x00AA0000
   int 0x40

...

mistaktes dd 0x10


Результат: ничего не выводится

Вопрос: где ошибка? :mrgreen:

Author:  dunkaist [ Mon Jul 19, 2010 12:26 pm ]
Post subject:  Re: Начинающий

Андрей Михайлович wrote:
Code:
draw_integer:   
   mov eax, 47
   mov ebx, 00000000000000000001000000000000b
   mov ecx, [mistakes]
   mov edx, 70*65536+25
   mov esi, 0x00AA0000
   int 0x40

...

mistaktes dd 0x10


взято из http://diamond.kolibrios.org/klbr_doc.chm:
bl = 0 - ecx содержит число
bl = 1 - ecx содержит указатель на dword/qword-число
bh = 0 - отображать в десятичной системе счисления
bh = 1 - отображать в шестнадцатеричной системе
bh = 2 - отображать в двоичной системе
биты 16-21 = сколько цифр отображать
биты 22-29 зарезервированы и должны быть установлены в 0
бит 30 установлен = выводить qword (64-битное число); при этом должно быть bl = 1
бит 31 установлен = не выводить ведущие нули числа

В приведённом коде bh равно 16, а не 0, 1 ил 2, да и биты 16-21(сколько цифр отображать) нулевые.
Если я правильно понял, код должен выводить десятичное число 16-ю цифрами. Тогда в ebx нужно записать 00000000000100000000000000000000b. Ещё проще и удобнее использовать запись в 16-ричном виде: 0x00100000.

На всякий случай:
ebx=0x11223344
bx=0x3344
bh=0x33
bl=0x44

Author:  Андрей Михайлович [ Mon Jul 19, 2010 1:42 pm ]
Post subject:  Re: Начинающий

Господи, ну конечно!!!

Регистр ebx ведь имеет вид [16 безымянных бит][bh][bl]

А я сделал всё наоборот! Считал биты не с того конца...

dunkaist, спасибо!

Author:  Андрей Михайлович [ Tue Jul 20, 2010 7:56 am ]
Post subject:  Re: Начинающий

Ещё один вопросик!

Вот заголовок программы.

Code:
 db 'MENUET01'
 dd 0x01
 dd START
 dd I_END
 dd 0x1000
 dd 0x1000
 params dd 0x0
 dd 0x0


Мне нужно получить параметры командной строки.

Я запускаю программу, она ведёт себя так, как будто бы никаких параметров задано не было.

Code:
cmp [params], 0x0
je no_param

Перебрасывает на метку no_param

Тогда я запускаю отладчик, ввожу
Code:
load /rd/1/myapp /rd/1/myfile.txt


По адресу 0x0000001С мы видим:
Code:
00 00 00 00

, то бишь одни нули...

Никак не могу понять, что я делаю не так...

Author:  Asper [ Tue Jul 20, 2010 8:36 am ]
Post subject:  Re: Начинающий

Code:
db 'MENUET01'
dd 0x01
dd START
dd I_END
dd 0x1000
dd 0x1000
dd params
dd 0x0

;.............


; Unitialized data section

params rb 1024

Page 5 of 12 All times are UTC+03:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/