Código
Elementos en Orden de Dibujado de Línea Bresenham | --------------------------------------------------------- | void OPCODE__graphics__Bresenham_line(unsigned char *BresenObj) | ---- - Elementos: tipo de diagonal: Bresenham_line__slope controles x y: Bresenham_line__xctrl, Bresenham_line__yctrl largo x y: Bresenham_line__xlargo, Bresenham_line__ylargo coordenada mayor (sin signo): Bresenham_line__maxcoord Bresenham_line__xdireccion, Bresenham_line__ydireccion, suman 1 o -1 Bresenham_line__draw hace más eficiente per no es necesario para saber cuándo dibujar 1 pixel. - Tipo de diagonal (slope), horizontal 1, vertical 2, Bresenham diagonal 0 (al final, sin chequeo). - Controles x y y de errores de cálculo. - largo x = xfin-xinicio (con signo). largo y = yfin-yinicio (con signo). El signo es para detectar si la dirección suma o resta. - Para x y y: Vemos si el largo es 0. Si es 0, lo ponemos a 1. Sino, la dirección es largo/abs(largo), es 1 o -1. - Para x y y: Ajustar largo a abs(largo)+1 para perder el signo necesario para las direcciones x y, y convertir el rango de coordenadas en cuenta natural. Parece que necesitamos sumar 1 y usar un do while con actualización HASTA EL FINAL para cubrir el primer y último pixel con una ÚNICA operación de putpixel. - Para obtener la coordenada más larga: Si xlargo==ylargo, coordenadamayor=xlargo Si xlargo>ylargo, coordenadamayor=xlargo Si ylargo>xlargo, coordenadamayor=ylargo Copiamos a coordenadamayor2 para el bucle. - Si slope es 1, dibujar vertical, si es 2, horizontal. Terminar. - Esto inicializa los valores. do { //Esto indica el momento más óptimo //para dibujar cada pixel: /// Bresenham_line__draw=0; //Control de X: /// if(Bresenham_line__xctrl)>Bresenham_line__maxcoord)) { Bresenham_line__xctrl)-=Bresenham_line__maxcoord); Bresenham_line__x)+=Bresenham_line__xdireccion); Bresenham_line__draw=1; } //Control de Y: /// if(Bresenham_line__yctrl)>Bresenham_line__maxcoord)) { Bresenham_line__yctrl)-=Bresenham_line__maxcoord); Bresenham_line__y)+=Bresenham_line__ydireccion); Bresenham_line__draw=1; } Bresenham_line__xctrl)+=Bresenham_line__xlargo); Bresenham_line__yctrl)+=Bresenham_line__ylargo); } while(Bresenham_line__maxcoord)-=1);
Código de la función:
Código
//Estructura común de funciones gráficas //de solo calcular comunes donde las 2 primeras variables //son widewords x y y y la siguiente es el final de la //operación si es 2, o el inicio si es 0. /// #define Bresenham_line__x wideword_sz*0 #define Bresenham_line__y wideword_sz*1 #define Bresenham_line__inited wideword_sz*2 #define Bresenham_line__slope wideword_sz*3 #define Bresenham_line__xstart wideword_sz*4 #define Bresenham_line__ystart wideword_sz*5 #define Bresenham_line__xend wideword_sz*6 #define Bresenham_line__yend wideword_sz*7 #define Bresenham_line__colorpx wideword_sz*8 #define Bresenham_line__xdireccion wideword_sz*9 #define Bresenham_line__ydireccion wideword_sz*10 #define Bresenham_line__xlargo wideword_sz*11 #define Bresenham_line__ylargo wideword_sz*12 #define Bresenham_line__maxcoord wideword_sz*13 #define Bresenham_line__maxcoord2 wideword_sz*14 #define Bresenham_line__xctrl wideword_sz*15 #define Bresenham_line__yctrl wideword_sz*16 void OPCODE__graphics__Bresenham_line(unsigned char *BresenObj) { // long xdireccion,ydireccion; //1 o -1 // long xlargo,ylargo; //valor absoluto de largo+1 // long coordenadamayor,coordenadamayor2; //si x o y es mayor // long xctrl=0,yctrl=0; //controlar el pixel a dibujar excediendo la longitud de coordenadas de la línea if(*(long*)(BresenObj+Bresenham_line__inited)==2)return; if(!( *(long*)(BresenObj+Bresenham_line__inited) )) { *(long*)(BresenObj+Bresenham_line__inited)=1; *(long*)(BresenObj+Bresenham_line__slope)=0; *(long*)(BresenObj+Bresenham_line__xctrl)=0; *(long*)(BresenObj+Bresenham_line__yctrl)=0; *(long*)(BresenObj+Bresenham_line__xlargo)=*(long*)(BresenObj+Bresenham_line__xend)-*(long*)(BresenObj+Bresenham_line__xstart); *(long*)(BresenObj+Bresenham_line__ylargo)=*(long*)(BresenObj+Bresenham_line__yend)-*(long*)(BresenObj+Bresenham_line__ystart); if(*(long*)(BresenObj+Bresenham_line__xdireccion)) *(long*)(BresenObj+Bresenham_line__xdireccion)=*(long*)(BresenObj+Bresenham_line__xlargo)/myabs_long(*(long*)(BresenObj+Bresenham_line__xlargo)); else *(long*)(BresenObj+Bresenham_line__xdireccion)=1; if(*(long*)(BresenObj+Bresenham_line__ydireccion)) *(long*)(BresenObj+Bresenham_line__ydireccion)=*(long*)(BresenObj+Bresenham_line__xlargo)/myabs_long(*(long*)(BresenObj+Bresenham_line__ylargo)); else *(long*)(BresenObj+Bresenham_line__ydireccion)=1; *(long*)(BresenObj+Bresenham_line__xlargo)=myabs_long(*(long*)(BresenObj+Bresenham_line__xlargo))+1; *(long*)(BresenObj+Bresenham_line__ylargo)=myabs_long(*(long*)(BresenObj+Bresenham_line__ylargo))+1; *(long*)(BresenObj+Bresenham_line__maxcoord)=*(long*)(BresenObj+Bresenham_line__xlargo); //si xlargo==ylargo if(*(long*)(BresenObj+Bresenham_line__xlargo)>*(long*)(BresenObj+Bresenham_line__ylargo))*(long*)(BresenObj+Bresenham_line__maxcoord)=*(long*)(BresenObj+Bresenham_line__xlargo); if(*(long*)(BresenObj+Bresenham_line__ylargo)>*(long*)(BresenObj+Bresenham_line__xlargo))*(long*)(BresenObj+Bresenham_line__maxcoord)=*(long*)(BresenObj+Bresenham_line__ylargo); *(long*)(BresenObj+Bresenham_line__maxcoord2)=*(long*)(BresenObj+Bresenham_line__maxcoord)+1; *(long*)(BresenObj+Bresenham_line__x)=*(long*)(BresenObj+Bresenham_line__xstart); *(long*)(BresenObj+Bresenham_line__y)=*(long*)(BresenObj+Bresenham_line__ystart); } //Vertical (no Bresenham): /// if(*(long*)(BresenObj+Bresenham_line__slope)==1 || *(long*)(BresenObj+Bresenham_line__xstart)==*(long*)(BresenObj+Bresenham_line__xend)) { *(long*)(BresenObj+Bresenham_line__slope)=1; //vert if(*(long*)(BresenObj+Bresenham_line__y)==*(long*)(BresenObj+Bresenham_line__yend)) *(long*)(BresenObj+Bresenham_line__inited)=2; else *(long*)(BresenObj+Bresenham_line__y)+=(*(long*)(BresenObj+Bresenham_line__ydireccion)); return; } //Horizontal (no Bresenham): /// if(*(long*)(BresenObj+Bresenham_line__slope)==2 || *(long*)(BresenObj+Bresenham_line__ystart)==*(long*)(BresenObj+Bresenham_line__yend)) { *(long*)(BresenObj+Bresenham_line__slope)=2; //horiz if(*(long*)(BresenObj+Bresenham_line__x)==*(long*)(BresenObj+Bresenham_line__xend)) *(long*)(BresenObj+Bresenham_line__inited)=2; else *(long*)(BresenObj+Bresenham_line__x)+=(*(long*)(BresenObj+Bresenham_line__xdireccion)); return; } if(*(long*)(BresenObj+Bresenham_line__xctrl)>*(long*)(BresenObj+Bresenham_line__maxcoord)) { *(long*)(BresenObj+Bresenham_line__xctrl)-=*(long*)(BresenObj+Bresenham_line__maxcoord); *(long*)(BresenObj+Bresenham_line__x)+=*(long*)(BresenObj+Bresenham_line__xdireccion); } if(*(long*)(BresenObj+Bresenham_line__yctrl)>*(long*)(BresenObj+Bresenham_line__maxcoord)) { *(long*)(BresenObj+Bresenham_line__yctrl)-=*(long*)(BresenObj+Bresenham_line__maxcoord); *(long*)(BresenObj+Bresenham_line__y)+=*(long*)(BresenObj+Bresenham_line__ydireccion); } *(long*)(BresenObj+Bresenham_line__xctrl)+=*(long*)(BresenObj+Bresenham_line__xlargo); *(long*)(BresenObj+Bresenham_line__yctrl)+=*(long*)(BresenObj+Bresenham_line__ylargo); if(*(long*)(BresenObj+Bresenham_line__x)==*(long*)(BresenObj+Bresenham_line__xend) && *(long*)(BresenObj+Bresenham_line__y)==*(long*)(BresenObj+Bresenham_line__yend)) *(long*)(BresenObj+Bresenham_line__inited)=2; }
Ejemplo de uso:
Código
unsigned char bresenObj0[wideword_sz*17]; *(long*)(bresenObj0+Bresenham_line__inited)=0; *(long*)(bresenObj0+Bresenham_line__xstart)=0; *(long*)(bresenObj0+Bresenham_line__ystart)=0; *(long*)(bresenObj0+Bresenham_line__xend)=319; *(long*)(bresenObj0+Bresenham_line__yend)=199; while(1) { OPCODE__graphics__Bresenham_line(bresenObj0); putpixel(*(long*)(bresenObj0+Bresenham_line__x), *(long*)(bresenObj0+Bresenham_line__y), 6); if(*(long*)(bresenObj0+Bresenham_line__inited)==2)break; }