Šta je novo?

Algoritam za liniju

  • Začetnik teme Začetnik teme poopBot
  • Datum pokretanja Datum pokretanja
P

poopBot

Guest
Da li je koristio neko, alogoritam za liniju, ja pokusavam vec ceo dan, al nesto mi nevalja, linije mi nemaju konstantu debljinu a neznam zasto 🙁
Vodio sam se ovom knjigom http://members.chello.at/~easyfilter/Bresenham.pdf

Kod:
void plotLineWidth(int x0, int y0, int x1, int y1, float wd)
	{ // plot an anti-aliased line of width wd 
		int dx = Mathf.Abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
		int dy = Mathf.Abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
		int err = dx - dy, e2, x2, y2; // error value e_xy 
		float ed = dx + dy == 0 ? 1 : Mathf.Sqrt((float)dx * dx + (float)dy * dy);

		for (wd = (wd + 1) / 2; ;) { // pixel loop 
			SetPixelMyImg(x0, y0);
			e2 = err; x2 = x0;

			if (2 * e2 >= -dx) { // x step 
				for (e2 += dy, y2 = y0; e2 < ed * wd && (y1 != y2 || dx > dy); e2 += dx) {
					y2 += sy;
					SetPixelMyImg(x0, y2);
				}

				if (x0 == x1) break;
				e2 = err; err -= dy; x0 += sx;
			}
			if (2 * e2 <= dy) { // y step 
				for (e2 = dx - e2; e2 < ed * wd && (x1 != x2 || dx < dy); e2 += dy) {
					x2 += sx;
					SetPixelMyImg(x2, y0);
				}

				if (y0 == y1) break;
				err += dx; y0 += sy;
			}
		}
	}

Pokusavam da napravim bojanku, tj postoji crno bela slika i ispod nje slika u boji. Ja brisem ovu crno belu, koja je lejer iznad obojene, kako bi dobio boju ispod.... Inace vec imam kruzne algoritme za pocetak i kraj linije al dzabe mi to kad mi linija deformisana na kvadrat

Linje.png
Na slici sam sve linije izvalcio iz jedne tacke u sredini ka spolja u krug...

Ako neko ima kod za liniju koji bi serovo ili ako je neko raspolozen za umni rad neka javi 🙂 idiem da prosetam malo mozda pomogne xD
 
Poslednja izmena od urednika:
Ne znam da li si vec nasao resenje, ali algoritam ti je preslikan Bersenhamov kao u knjizi. Zasto si siguran da je ovde problem? Ja bi rekao da zoves metodu sa pogresnim parametrima, tj da je problem na nekom drugom mestu.
 
Pa siguran sam da je ovde problem jer ono stvarno neznam kako bi mogao da zovem metodu sa pogresnim parametrima, na ovoj slici sam uzimao input od misa kao x1 i y1 dok sam za x i y uzeo cetar otprilike tipa 200, 300... Na unity forumu like mi je reko da trebam da uracunam nesto posebno ako je Y>X ili tako nesto mada iskreno nekontam bas sta kaze https://forum.unity3d.com/threads/thick-line-c.453837/

Mislim da sav vec proveravao sta dajem metodi al evo provericu opet
 
To sto ti je napisao kapiram da je mislio generalno za Brensenhama. Kod tog algoritma moras da postujes dve stvari, prva je da prava ima ne-negativan nagib i drugi uslov je da ako ti je linija koju crtas zadata pomocu a1 i a2, mora da vazi da je a1.x < a2.x, prostije receno da je a1 levo od a2.
Ako je nagib < 0, onda je algoritam nesto drugaciji. E sad opet ti kazem posto ti je algoritam preslikan iz knjige, verovatno su vodili racuna o tim stvarima.
 
To sto ti je napisao kapiram da je mislio generalno za Brensenhama. Kod tog algoritma moras da postujes dve stvari, prva je da prava ima ne-negativan nagib i drugi uslov je da ako ti je linija koju crtas zadata pomocu a1 i a2, mora da vazi da je a1.x < a2.x, prostije receno da je a1 levo od a2.
Ako je nagib < 0, onda je algoritam nesto drugaciji. E sad opet ti kazem posto ti je algoritam preslikan iz knjige, verovatno su vodili racuna o tim stvarima.

Pa izgleda da nisu vodili racuna cim mi se suzava linija bez razloga, da nemas mozda neki Algoritam da mi preporucis koji radi bez plakanja, ili ako imas neku KASIKU da me nahranis xD
 
Ako je tako probaj da za linije desno od centra slike kod metode za prvu tacku stavis centar, a za drugu koordinate misa. Pa da vidimo sta ce da ispadne. :d
 
Pa ja trenutno za sve linije prvu tacku pravim iz centra a drugu od misa.... evo sad cu da probam da napravim bolji screenshot
PlacemPrekoInterneta.png

evo sliko nesto nevalja kad radim 90 bukvalno su duplo tanje nego kad su pod uglom, neznam stvarno dva dana umirem vec : (
 
Poslednja izmena od urednika:
Sto se Bresenhama tice, pogledaj ovu varijantu:
Kod:
void LineBresenham(int x1, int y1, int x2, int y2, int color)
{
    int dy = y2 - y1;
    int dx = x2 - x1;
    int stepx, stepy;

    if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
    if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
    dy <<= 1;        // dy is now 2*dy
    dx <<= 1;        // dx is now 2*dx

    drawpixel(x1,y1, color);
    if (dx > dy) 
    {
        int fraction = dy - (dx >> 1);  // same as 2*dy - dx
        while (x1 != x2) 
        {
           if (fraction >= 0) 
           {
               y1 += stepy;
               fraction -= dx;          // same as fraction -= 2*dx
           }
           x1 += stepx;
           fraction += dy;              // same as fraction -= 2*dy
           drawpixel(x1, y1, color);
        }
     } else {
        int fraction = dx - (dy >> 1);
        while (y1 != y2) {
           if (fraction >= 0) {
               x1 += stepx;
               fraction -= dy;
           }
           y1 += stepy;
           fraction += dx;
           drawpixel(x1, y1, color);
        }
     }
}
 
Sto se Bresenhama tice, pogledaj ovu varijantu:
Kod:
void LineBresenham(int x1, int y1, int x2, int y2, int color)
{
    int dy = y2 - y1;
    int dx = x2 - x1;
    int stepx, stepy;

    if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
    if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
    dy <<= 1;        // dy is now 2*dy
    dx <<= 1;        // dx is now 2*dx

    drawpixel(x1,y1, color);
    if (dx > dy) 
    {
        int fraction = dy - (dx >> 1);  // same as 2*dy - dx
        while (x1 != x2) 
        {
           if (fraction >= 0) 
           {
               y1 += stepy;
               fraction -= dx;          // same as fraction -= 2*dx
           }
           x1 += stepx;
           fraction += dy;              // same as fraction -= 2*dy
           drawpixel(x1, y1, color);
        }
     } else {
        int fraction = dx - (dy >> 1);
        while (y1 != y2) {
           if (fraction >= 0) {
               x1 += stepx;
               fraction -= dy;
           }
           y1 += stepy;
           fraction += dx;
           drawpixel(x1, y1, color);
        }
     }
}

Ovjo je za obicnu liniju koliko vidim meni treba jedna debela 🙂 , u swakom slucaju probacu kineza prvo , hvala
 
Imas ovde resenje koje je testirano i radi github.com/ArminJo/STMF3-Discovery-Demos/blob/master/lib/graphics/src/thickLine.cpp
Slican princip kao sto si radio na pocetku, mozes njega da analiziras, videces ima nekoliko implementacija, ako mene pitas gledaj poslednju void drawThickLineSimple(...);
 
Nije mi jasno kako si planirao da crtaš debele linije? Na prvi pogled se čini da pomeraš kvadrat po liniji. Pošto je taj kvadrat poravnat sa osama koordinatnog sistema, na početku i na kraju postoje ta suženja.
Ne znam kakav grafički API koristiš pa moraš da se petljaš sa ovim algoritmima. Rasterizacija mora pažljivo da se uradi da neki pixel ne bi ostao ugašen tamo gde ne treba.
Ako bi crtao popunjen krug umesto kvadrata dobio bi debele linije oblika kao plazma keks.
Ukoliko želiš da kosa debela linija bude podjednako debela, stvari se dodatno komplikuju, jer treba da popunjavaš potencijalne rupice u rasterizacija.


Sent from my Nexus 6P using Tapatalk
 
Updejt, porbao sa ovog linka http://rosettacode.org/wiki/Xiaolin_Wu's_line_algorithm#C.23 , uklopio ga u ono sto mi treba i na kraju skontao da "int thickness" nema veze sa zivotom nigde u kodu nije ni implementirana.....

Kako sto rekoh pokusavam da bojim kao u Paintu sa full kruznim brushom. Iskopao sam na netu algoritam za krug prvo i to radi, i onda sam krenuo kako sad od kruga napraviti liniju(ko plazma keks ), logicno napravis imaginarnu liniju i na svakih 1-2px nacrtas novi krug, i to radi nije problem ali nije effikasno laguje mnogo tipa zadam komandu i sacekam 5sec da mi izbaci liniju.. Sijalica radi i dolazim do zakljucka da onda logicna opcija je da nacrtam Krug na pocetku i kraju linije i izmedju izvucem liniju koristeci algoritam za liniju.

I eto stigo sam do problema, debela linije nece da saradjuje :smash:

Inace koristim glupi Unity3d i Texture2D.SetPixels32 ....

Sledeci pokusaj ovo sto mi oskar preporucio cpp... Dug je dan 🙂
 
Poslednja izmena od urednika:
x = x1;
y= y1;
dx = x2-x1;
dy= y2-y1;
e = 2dy –dx;
for i=1 to dx {
plot(x,y);
e1 = e + 2dy;
if e>0 then {
y=y+1;
e = e1 – 2dx;
}
x=x+1;
}

ovo ti je onako uproscen celobrojan algoritam, posto su celobrojne operacije jeftinije

u sustini imas zadatu pocetnu i krajnju tacku i treba da rasterski nacrtas liniju tako sto ces ofarbati potrebne piksele izmedju dve zadate tacke i tako dobiti najbolju aproksimaciju linije

mozes da farbas piksele koji su desno ili dijagonalno desno gore i to mi pada na pamet kao jedini razlog zasto ti je drugacija debljina linije, jer mozda alat koji koristis to nekako cudno interpretira
 
Poslednja izmena:
x = x1;
y= y1;
dx = x2-x1;
dy= y2-y1;
e = 2dy –dx;
for i=1 to dx {
plot(x,y);
e1 = e + 2dy;
if e>0 then {
y=y+1;
e = e1 – 2dx;
}
x=x+1;
}

ovo ti je onako uproscen celobrojan algoritam, posto su celobrojne operacije jeftinije

u sustini imas zadatu pocetnu i krajnju tacku i treba da rasterski nacrtas liniju tako sto ces ofarbati potrebne piksele izmedju dve zadate tacke i tako dobiti najbolju aproksimaciju linije

mozes da farbas piksele koji su desno ili dijagonalno desno gore i to mi pada na pamet kao jedini razlog zasto ti je drugacija debljina linije, jer mozda alat koji koristis to nekako cudno interpretira

Pa iskreno neznam sta cudno on moze da farba, ima textura koja je lupim 480x800 i komanda je bukvalno SetPixel(x,y,color).... Sad cu da probam ovo sto je oskar preporucio
 
Malo bolje al i dalje nevalja xD + dobio sam bonus neke texture krpe, sta ti je zivot kad hoces sve na mufte xD
CudnaDesavanja.png
 
To je sa algoritmom koji sam ti poslao? Na slici mi deluje mnogo bolje nego ranije. Sta ti je sada problem, da ujednacis debljinu sa krugovima na krajevima?
 
da, sa tim algoritmom ako ga nisam ostetio prilikom transletovanja na c#, pa bolje je nekazem da nije al nede propusta rupice ako vidis ko da ima neobojene piksele, recimo ova velika crta na desnoj strani bas se lepo vidi ko onaj materijal od krpe, a i to da nije debljina uvek ista
 
Batalio sam line algoritam, naso neki brzi circle i jos se tu malo poigrao
JosDaTestiramNaTelefonu.png
 
htedoh juce da ti kazem da probas algoritam za elipsu i krug isto bresenham, jer ne crtas obicne linije, ali reko mozda si se vec snasao
 
Super, bitno da si resio. Ja sam inace koristio Bresenhama u OpenGl - u za rasterizaciju i kruznice i linija, ne znam sto je tebe zezao, nemam iskustva sa Unity, al nije ni bitno sada. :d
 
Hvala sivim drugaricima na ulozenom trudu 🙂
 
Poslednja izmena od urednika:
Ako koristiš unity i texture2d onda pređi na rendertexture i koristi gl grafičke operacije. Setpixel je najsporiji mogući način za crtanje.

Sent from my Nexus 6P using Tapatalk
 
Ako koristiš unity i texture2d onda pređi na rendertexture i koristi gl grafičke operacije. Setpixel je najsporiji mogući način za crtanje.

Sent from my Nexus 6P using Tapatalk

Ok hvala na savetu, mozda neki drugi put trenutno sam zavrsio ovako
 
Nazad
Vrh Dno