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
Результат: ничего не выводится

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

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
Мне нужно получить параметры командной строки.

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

Code: Select all

cmp [params], 0x0
je no_param
Перебрасывает на метку no_param

Тогда я запускаю отладчик, ввожу

Code: Select all

load /rd/1/myapp /rd/1/myfile.txt
По адресу 0x0000001С мы видим:

Code: Select all

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

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

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