Page 5 of 12
Re: Начинающий
Posted: Fri Sep 04, 2009 12:59 am
by Mario
Относительно давно, когда я реализовывал на Фокале (на БК-0010) рисование окружности (функции не было, рисовал сначала точками, потом отрезками), в ходе экспериментов выяснил что при рисовании отрезками достаточно шага:
I = sqrt (R), (квадратный корень радиуса)
Соответственно окружность радиусом 50 состоит из 2Pi * R / I = 44 отрезков (с округлением 45, потому что окружность должна быть замкнута).
R100 = 63
R75 = 54
R50 = 45
R30 = 35
R10 = 19
R5 = 14
Конечно окружность получается немного угловатой, но думаю это можно использовать как базу. Например во Flash в родном плеере можно выбрать три уровня плавности отрисовки.
Как преимущество достаточно высокая скорость.
В твоем случае придется разбивать кривую на отрезки и вычислять для каждого отрезка свой радиус.
Re: Начинающий
Posted: Fri Sep 04, 2009 10:50 am
by tsdima
Кстати, я был немало удивлён, когда увидел вот такой простой алгоритм вычёрчивания окружности:
Code: Select all
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
Re: Начинающий
Posted: Fri Sep 04, 2009 12:42 pm
by Leency
А что означает строка "px = 0: py = r"?
На Си это будет выглядеть просто
px = 0; py = r;
?
Re: Начинающий
Posted: Fri Sep 04, 2009 12:50 pm
by Albom
да, именно так и будет выглядеть.
Re: Начинающий
Posted: Fri Sep 04, 2009 1:22 pm
by Leency
tsdima
Действительно работает.
Code: Select all
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;
}
}
Re: Начинающий
Posted: Fri Sep 04, 2009 2:01 pm
by Mario
Есть у метода один небольшой минус - в некоторых участках толщина линии не 1 пиксел, а 2.
Я правда не знаю может быть при рисовании отрезками тоже апроксимация может выдать такой финт ушами, а может и нет - надо проверять. Однако отсуствие Sin и Cos видимо значительно ускоряют отрисовку.
Только мне вот нифига не понятно зачем программе 1 Мб памяти? Уж Kfar насколько более сложная программа, но со всеми данными при запуске сожрал только чуть более 600 Кб...
Неужели нельзя в Си как в Fasm сделать вычисление размера при компиляции?
Re: Начинающий
Posted: Fri Sep 04, 2009 3:53 pm
by Leency
Mario
Думаю, можно. Не секрет, что я плохой программист, но на безрыбье и рак рыба.
Есть вот такая структура в kolibri.h--
Code: Select all
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: Select all
dword alloc_mem = #stop+1032;//0x00100000;
dword x86esp_reg = #stop+1032;//0x00100000;
Вроде работает, для circle, но тот же HTMLv отказывается работать с такими значениями. Наверное, именно в них вся загвоздка.
Re: Начинающий
Posted: Fri Sep 04, 2009 6:34 pm
by Mario
Вот так гораздо лучше - теперь код занимает только 4 Кб (минимальный размер страницы памяти).
но тот же HTMLv отказывается работать с такими значениями. Наверное, именно в них вся загвоздка.
Есть 2 предположения:
1) Какойто участок твоего собственного кода портит область стека.
2) Размер стека недостаточен - попробуй 4096 или больше.
Кстати лучше немного увеличить:
dword menu_stak[100]=0;
Любой стек лучше брать с запасом, неизвестно насколько разрастется проект.
Re: Начинающий
Posted: Fri Sep 04, 2009 9:19 pm
by tsdima
Mario wrote:Есть у метода один небольшой минус - в некоторых участках толщина линии не 1 пиксел, а 2.
Я правда не знаю может быть при рисовании отрезками тоже апроксимация может выдать такой финт ушами, а может и нет - надо проверять.
Стандартный алгоритм Брезенхема для линии не делает "такой финт ушами". Можно в вышеописанном алгоритме запоминать координаты двух последних точек, и если три точки стоят рядом, то предпоследнюю не рисовать. Во всяком случае это будет быстрее чем синус.
Re: Начинающий
Posted: Fri Sep 04, 2009 9:27 pm
by Mario
Ну, так ведь я и не спорил насчет производительности (почитай мой слова повнимательней), а если есть способ улучшить алгоритм, то замечательно.
Re: Начинающий
Posted: Mon Jul 19, 2010 10:40 am
by Андрей Михайлович
Приветствую! Дабы не создавать новую тему, спрошу здесь.
Задача:
Вывести число из переменной
mistakes
Код:
Code: Select all
draw_integer:
mov eax, 47
mov ebx, 00000000000000000001000000000000b
mov ecx, [mistakes]
mov edx, 70*65536+25
mov esi, 0x00AA0000
int 0x40
...
mistaktes dd 0x10
Результат: ничего не выводится
Вопрос:
где ошибка?
Re: Начинающий
Posted: Mon Jul 19, 2010 12:26 pm
by dunkaist
Андрей Михайлович wrote:Code: Select all
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
Re: Начинающий
Posted: Mon Jul 19, 2010 1:42 pm
by Андрей Михайлович
Господи, ну конечно!!!
Регистр ebx ведь имеет вид [16 безымянных бит][bh][bl]
А я сделал всё наоборот! Считал биты не с того конца...
dunkaist, спасибо!
Re: Начинающий
Posted: Tue Jul 20, 2010 7:56 am
by Андрей Михайлович
Ещё один вопросик!
Вот заголовок программы.
Code: Select all
db 'MENUET01'
dd 0x01
dd START
dd I_END
dd 0x1000
dd 0x1000
params dd 0x0
dd 0x0
Мне нужно получить параметры командной строки.
Я запускаю программу, она ведёт себя так, как будто бы никаких параметров задано не было.
Перебрасывает на метку no_param
Тогда я запускаю отладчик, ввожу
По адресу 0x0000001С мы видим:
, то бишь одни нули...
Никак не могу понять, что я делаю не так...
Re: Начинающий
Posted: Tue Jul 20, 2010 8:36 am
by Asper
Code: Select all
db 'MENUET01'
dd 0x01
dd START
dd I_END
dd 0x1000
dd 0x1000
dd params
dd 0x0
;.............
; Unitialized data section
params rb 1024