forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Основной форум (http://forum.boolean.name/forumdisplay.php?f=49)
-   -   Отрисовка толстых линий (http://forum.boolean.name/showthread.php?t=11746)

Tronix 22.01.2010 20:58

Ответ: Ошибка синтаксиса.
 
Цитата:

Сообщение от VotapilD (Сообщение 134427)
O_O А не долговато ли? Толстую линию по Брезенхаму?

Да нет вроде. Ну можно по DDA, оно вообще летает
UPD: А не, DDA тот еще тормоз, ибо деление....

Tronix 23.01.2010 01:08

Ответ: Ошибка синтаксиса.
 
Вложений: 1
Вообще не нужны никакие брезенхамы имхо. Толстая линия - это всего лишь много тонких линий и не более )) Вот прям щаз на коленке накатал. Если не задавать гигантскую ширину, вполне может прокатить ))) Писалось за 5 мин, поэтому если сильно накосячил прошу не пинать больно.
PHP код:

program NewProject2;
//
// Simle draw lines with width demo program. (c) Tronix, 2010.
//
Var
gw,gh integer;        // screen width and height
xx1,xx2,
yy1,yy2 integer// random coordinates for line
width integer;        // line width

// Very simple procedure for drawing lines with any width
// x1,y2,x2,y2 - screen coordinates
// d - line width
Procedure BigLine(x1,y1,x2,y2,dinteger);
Var 
iswap integer;
Begin
    
If x1 x2 then             // vertical line
        
Begin
            
For := d div 2 d to d div 2 do DrawLine(x1+i,y1,x2+i,y2);
        
End
    
else
    If 
y1 y2 then            // horizontal line
        
Begin
            
For := d div 2 d to d div 2 do DrawLine(x1,y1+i,x2,y2+i);
        
End
    
else
        
Begin
            DrawLine
(x1,y1,x2,y2);        // draw sinle line
            
If 1 then                      // if width > 1 then draw left and right lines
                
Begin
                    
If x1 x2 then                // sorting coordinates if needed
                        
Begin
                            swap 
:= x2;
                            
x2 := x1;
                            
x1 := swap;
                            
swap := y2;
                            
y2 := y1;
                            
y1 := swap;
                        
End;
                    If (
x1 x2) and (y1 y2then     // detect line direction
                        
Begin                                                         // left-to-right line
                            
For := 1 to d div 2 do                
                                
Begin
                                    DrawLine
(x1,y1+i,x2-i,y2); //left side
                                    
DrawLine(x1+i,y1,x2,y2-i); //right side
                                
End
                        End
                        
else                                                         // righ-to-left line
                            
Begin
                            
For := 1 to d div 2 do
                                
Begin
                                    DrawLine
(x1+i,y1,x2,y2+i); // left side
                                    
DrawLine(x1,y1-i,x2-i,y2); // right side
                                
End
                        End
;
            
End;
    
End//if
End;

begin
    Randomize
;
    
gw := GetWidth;
    
gh := GetHeight;
    
SetColor(0,0,0);
    
FillRect(0,0,gw,gh);    // clear screen. black
    
    
repeat
        xx1 
:= Random(gw);
        
yy1 := Random(gh);        // random line coordinates
        
xx2 := Random(gw);
        
yy2 := Random(gh);
        
width := Random(10)+1// line width >= 1

        
SetColor(Random(255),Random(255),Random(255)); // random color for line
        
bigLine(xx1,yy1,xx2,yy2,width);                              // DRAW it Now :)))

        
SetColor(255,255,255);                                 // white color for debug msg
        
DrawText('X1= '+xx1+' Y1= '+yy1,0,0);
        
DrawText('X2= '+xx2+' Y2= '+yy2,0,10);
        
DrawText('W= '+width,0,20);                        // draw debug information

        
repaint;    
        
repeat delay (10until getkeyclicked <> KE_NONE;  // waiting for any key
        
SetColor(0,0,0); // clear screen
        
FillRect(0,0,gw,gh);
        
repaint;
    
until GetKeyPressed KE_STAR// exit if 'star' key will be pressed
end


ViNT 23.01.2010 01:54

Ответ: Ошибка синтаксиса.
 
Нашел в нете упоминание о классе Graphics2D для java, там есть разные стили линий, и другие графические инструменты, попробую под него либу накатать (если NetBeans на семерку встанет).

Tronix 23.01.2010 12:27

Ответ: Ошибка синтаксиса.
 
Вложений: 1
А вообще погорячился я. Интересная задачка на самом деле... После некоторых раздумий пришел к банальному - рисуем основную линию по Брезенхему, причем из каждой нарисовоной точки рисуем еще одну линиию перпендикулярно нашей основной линии.

Ну либо тупо рисовать закрашенный полигон, но это уже деление-умножение, причем подозреваю вешественное. Хотя не известно что еще быстрее будет...

UPD: ыыыыы, оказывается изобрел велосипед - http://homepages.enterprise.net/murp...ine/index.html :)

VotapilD 23.01.2010 14:19

Ответ: Ошибка синтаксиса.
 
А что если и правда sin&cos? Седне в школе по памяти на алгебре(на контрольной=) ) накатал:

a:=abs(x1-x2);//катит у
b:=abs(y1-y2);//катит х
c:=sqrt(a*a+b*b);//гипотенуза
cos:=b/c;//cosB
sin:=a/c;//sinB угол против стороны У
for i:=-2 to 2 do begin
x1:=x1+cos*i;//
y1:=y1+sin*i;// Переносим точки, так
x2:=x2+cos*i;// чтобы линия была параллельна...
y2:=y2+sin*i;//
DrawLine(trunc(x1),trunc(y1),trunc(x2),trunc(y2));
end;
repaint;

Павел, я правильно вас понял?
Цитата:

Сообщение от Павел (Сообщение 133743)
А вообще у линии есть угол , вот собственно толстая линия - это несколько обычных линий под одним и тем же углом. Значит, к координате X надо прибавлять косинус угла, а к Y - синус. Учите тригонометрию :)

Проверте плиз. Я щас без телефона, а эмуль под линь я пока не нашёл... И если это правильно то останется лишь придумать способ увеличение длины отрезка по краям)

VotapilD 23.01.2010 14:54

Ответ: Ошибка синтаксиса.
 
Выбрался к винде.. Что-то не то....
Код:

program sincos;
var x1,x2,y1,y2,a,b,c,cos,sin:real;
i:integer;
begin
x1:=0;
y1:=0;
x2:=100;
y2:=100;
a:=abs(trunc(x1-x2));//катит у
b:=abs(trunc(y1-y2));//катит х
c:=sqrt(a*a+b*b);//гипотенуза
cos:=b/c;//cosB
sin:=a/c;//sinB угол против стороны У
for i:=-2 to 2 do begin
x1:=x1+cos*i;//
y1:=y1+sin*i;//          Переносим точки, так
x2:=x2+cos*i;//                            чтобы линия была параллельна...
y2:=y2+sin*i;//
DrawLine(trunc(x1),trunc(y1),trunc(x2),trunc(y2));
end;
repaint;
delay(3000);
x1:=100;
y1:=100;
x2:=0;
y2:=100;
a:=abs(trunc(x1-x2));//катит у
b:=abs(trunc(y1-y2));//катит х
c:=sqrt(a*a+b*b);//гипотенуза
cos:=b/c;//cosB
sin:=a/c;//sinB угол против стороны У
for i:=-2 to 2 do begin
x1:=x1+cos*i;//
y1:=y1+sin*i;//          Переносим точки, так
x2:=x2+cos*i;//                            чтобы линия была параллельна...
y2:=y2+sin*i;//
DrawLine(trunc(x1),trunc(y1),trunc(x2),trunc(y2));
end;
repaint;
delay(3000);
x1:=0;
y1:=100;
x2:=50;
y2:=50;
a:=abs(trunc(x1-x2));//катит у
b:=abs(trunc(y1-y2));//катит х
c:=sqrt(a*a+b*b);//гипотенуза
cos:=b/c;//cosB
sin:=a/c;//sinB угол против стороны У
for i:=-2 to 2 do begin
x1:=x1+cos*i;//
y1:=y1+sin*i;//          Переносим точки, так
x2:=x2+cos*i;//                            чтобы линия была параллельна...
y2:=y2+sin*i;//
DrawLine(trunc(x1),trunc(y1),trunc(x2),trunc(y2));
end;
repaint;
delay(3000);
end;


Зато они параллельны! Это достижение)

cherepets 23.01.2010 16:51

Ответ: Ошибка синтаксиса.
 
VotapilD, nhal по wine работает.
в втк возможно эмуль входит, но яву я так и не смог поставить нормально(((

Tronix 23.01.2010 18:32

Ответ: Ошибка синтаксиса.
 
Вложений: 2
Не-не, sin/cos это все тормоза адовые. Да к тому-же еще и float-point. Щаз может полигонами запилю, будет как настоящая :)

UPD: Кое чего получается.... Осталось только код в порядок привести, или фиг с ним? )

Tronix 23.01.2010 20:36

Ответ: Ошибка синтаксиса.
 
Вложений: 2
Короче набросал вроде с помощью треугольников. Главный косяк - не помню вообще как найти точки ABCD (см рисунок). По обрывкам памяти и гуглу набросал, но чувствую что криво, што ппц.

Плюсы:
- быстро. В процедуре отрисовки треугольника только целочисленные числа. Единственное два деления на итерацию на inner_loop, но не критично.
- Когда вертикально или горизонтально - рисуем просто стандартным FillRect
- Когда ширина = 1 рисуем просто стандартно Line

Минусы:
- немного не точно, ибо либо с формулой точек ABCD косяк либо где-то чето не так округляется. Если не придираться - смотрица нормально.
- нельзя с помощью такого метода рисовать пунктирные линии например. Хотя с помощью небольшой допилки filltriangle можно. А если впилить простейшее текстурирование можно даже текстурами рисовать )))
Скриншоты всего этого безобразия выше.

Reizel 23.01.2010 20:42

Ответ: Ошибка синтаксиса.
 

Мой мозг никак не уймется. Автор, какая связь между названием темы и ее содержанием?? Может я что то не понимаю...

odd 23.01.2010 22:53

Ответ: Ошибка синтаксиса.
 
Что вы мучаетесь? Может мне легче библиотеку для рисования линии произвольной толщины написать? Будет работать немного быстрее и без глюков. Я вроде геометрию пока не всю забыл.

VotapilD 23.01.2010 23:02

Ответ: Ошибка синтаксиса.
 
Цитата:

Сообщение от Павел (Сообщение 134569)

Мой мозг никак не уймется. Автор, какая связь между названием темы и ее содержанием?? Может я что то не понимаю...

мне даже говорить стыдно...


Цитата:

Сообщение от Tronix
Короче набросал вроде с помощью треугольников. Главный косяк - не помню вообще как найти точки ABCD

Спасибо за идею, буду пробовать... Код какой-то странный, щас вот эмуль поставлю)

VotapilD 23.01.2010 23:03

Ответ: Ошибка синтаксиса.
 
Цитата:

Сообщение от odd (Сообщение 134581)
Что вы мучаетесь? Может мне легче библиотеку для рисования линии произвольной толщины написать? Будет работать немного быстрее и без глюков. Я вроде геометрию пока не всю забыл.

Давай)Я те вроде в ЛС писал))) Буду очень благодарен) И если можно, для вектора тоже)

Tronix 23.01.2010 23:16

Ответ: Ошибка синтаксиса.
 
Цитата:

Сообщение от odd (Сообщение 134581)
Что вы мучаетесь? Может мне легче библиотеку для рисования линии произвольной толщины написать? Будет работать немного быстрее и без глюков. Я вроде геометрию пока не всю забыл.

Да я собственно не мучаюсь, так просто время свободное было вот и предложил уже 2 варианта решения. Если первый смотрится конечно не очень (хотя мне нравятся острые концы у линии), то последний вполне себе кошерно выглядит на мой взгляд. Прям как во всяких модулях Graph турбопаскальных :) Кстати о каких именно глюках речь? В последнем варианте я их лично не наблюдаю.

Но если есть какие-то стандартные средства в яве, чтобы пилить толстые линии - то конечно проще сделать либу, чем так извращатся. :) Вообще будет полезная штука я думаю, особенно если с паттернами (прерывистая там, пунктирная и тд)

GRAY_WOLF 24.01.2010 10:59

Ответ: Ошибка синтаксиса.
 
Цитата:

Сообщение от odd (Сообщение 134581)
Что вы мучаетесь? Может мне легче библиотеку для рисования линии произвольной толщины написать? Будет работать немного быстрее и без глюков. Я вроде геометрию пока не всю забыл.

Еще бы и XML довел до ума, а то одни обрывки слов.


Часовой пояс GMT +4, время: 06:00.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot