glcd cizgi cizme algoritması problemi

Başlatan picman, 13 Aralık 2011, 11:21:20

picman

arkadaşlar gcld ile ekranda cizgi yapmaya çalışıyorum. internetten bulduğum örnek bir uygumadan yola cıkarak kendi glcd driver imi hazırlamaya çalışıyorum. aslında herşey güzel çalışıyor. fakat cizgi cizme fonksiyonunda minik bir problem var. cizginin baslangıc x,y koordinatları bitiş x,y koordinatlarından küçük ise bir problem yok çizgi düzgün çiziliyor. fakat tersi olduğunda yani çizginin bitis koordinatları baslangıc kooordinatlarından daha küçük olduğunda çizim yanlış bölgeye yapılıyor. fonksiyon aşağıdaki gibi.
void glcd_cizgi_ciz(signed int x0, signed int y0, signed int x1, signed char y1, char dolgu){ 
	unsigned char x,y,n,secim,temp; 
	signed int l,h;

	x=abs(x1-x0);   
	y=abs(y1-y0); 

	if (y > x){ 
		n=y; secim=1; 
		l=y; h=x;
	} 
	else{ 
		n=x; secim=0; 
		l=x; h=y;
	}

	for(i=0; i<=n; i++){ 
		switch(secim){
			case 1:{
				y=i+y0; 
				//x=(y*(x1-x0))/(y1-y0)+x0; 
				x=(y*h)/l+x0;
			}; break;
			case 0:{
				x=i+x0; 
				//y=(x*(y1-y0))/(x1-x0)+y0; 
				y=(x*h)/l+y0;
			}; break;
		}
		glcd_nokta(x,y,dolgu); 
	} 
}


daha önce glcd için kendi driver programını yapan var mı acaba. bu hi-tech in uğraştırıcı yapısı bazen insana bıkkınlık veriyor. hazır kütüphanesi olan bir dil mi kullansam neden uğraşıyorum diyorum bazen kendi kendime  ::)  ;D ama bu dil insan açok şey öğretiyor  :)
Bilgi paylaştıkça artar..

mufitsozen

baslangıc x,y koordinatları bitiş x,y koordinatlarından küçük degil ise ise fonksiyonun basinda bunlari degistirin. Yani x0,y0 dan x1,y1 e bir cizgi cizeceginize x1,y1 den x0,y0 a bir cizgi cizin.

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

Pir-O

Bence sorun abs() fonksiyonunda onun yerine
if (x0>x1) 
    x=x0-x1;
else 
    x=x1-x0;

if(y0>y1)
    y=y0-y1;
else 
    y=y1-y0;


olursa sorun düzelir diye düşünüyorum.

picman

internetten bulduğum başka bir kod ile şimdi deüzgün çalışıyor. istediğim koordinatı verip çizgi çizebiliyorum artık. fakat bu algoritma hangi mantık ile oluşturulmuş anlamadım açıkçası. bu algoritmanın nasıl oluşturulduğu hakkında fikri olan var mı . neyin nasıl olduğunu bilerek ilerlemek istiyorum da  ;D
void glcd_cizgi_ciz(signed int x1, signed int y1, signed int x2, signed int y2, char dolgu)
{
   signed int  x, y, addx, addy, dx, dy;
   signed long P; int i;
   
   dx = abs(x2 - x1); 
   dy = abs(y2 - y1);
   x = x1; y = y1;
   
   if(x1 > x2)
      addx = -1;
   else
      addx = 1;

   if(y1 > y2)
      addy = -1;
   else
      addy = 1;

   if(dx >= dy){
      P = 2*dy - dx;
      for(i=0; i<=dx; ++i){
         glcd_nokta(x,y,dolgu);
         if(P<0){
            P+=2*dy; x+=addx; 
         }
		 else{
            P+=2*dy - 2*dx;
            x+=addx; y+=addy;
         }
      }
   }
   else{
      P = 2*dx - dy;
      for(i=0; i<=dy; ++i){
         glcd_nokta(x,y,dolgu);
         if(P<0){
            P+=2*dx; y+=addy;
         }
         else{
            P+=2*dx - 2*dy;
            x+=addx; y+=addy;
         }
      }
   }
}


birde kodlar biraz yavaş çalışıyor. daha fazla işlem yapılmış sanırım ondan..
Bilgi paylaştıkça artar..

Burak B

#4
Benim baya bir fikrim var ama açıklama için çok yer ve zaman lazım o yüzden. Basitçe çizginin üzerinden geçtiği farzedilen pikseller üzerinde yaklaşımsal hesaplamalar yapılır. Böylece pixel konumu veya antialias kullanılacaksa rengi hesaplanır diyerek. Link vermekle yetineceğim.

Line Drawing Algorithms

Bresenham's Line Algo - Not: Bresenham Antialias Kullanmaz. Ama Kayan nokta yerine. Tam sayılarla çalıştığı için çok hızlıdır.

Bresenham's Line Algo - Detaylı

Wu's Line Algorithm - Not : Antialias destekler. Kayan nokta yerine sabit noktalı gerçek sayılar kullanırsanız daha hızlı olacaktır ki örneklerde de fixed point kullanılmıştır.

Hugo Elias' ın elinden Wu' nun Çizgi algoritmasının anlatımı. - Hugo Elias abimiz saygıdeğer bir abimizdir. Diğer yazılarınada gözatabilirsiniz.

Bunlar benim sevdiğim ve yaygın kullanılan iki algoritma bunun yanısıra DDA(digital differential analyzer) yaklaşımlı çizgi algoritmaları ve benzerleri nette mevcut. Google a "Line Drawing Algorithms" yazın yeter.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle