Funcion para dibujar triangulos

Started by carles, June 12, 2010, 09:22:16 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

carles


He hecho una funcion para dibujar triangulos ya que no encontre la correspondiente en bennu.

[code language="bennu"]
Program Triangle;

Global
   angulo1;
   distancia1=100;
begin
   set_mode(320,240,16);
   set_fps(30,0);
   write_var(0,0,0,0,fps);
   
   loop
      if(key(_esc)) exit(); end
      triangle(get_distx(angulo1,distancia1)+160,
         get_disty(angulo1,distancia1)+120,
         get_distx(angulo1+120000,distancia1)+160,
         get_disty(angulo1+120000,distancia1)+120,
         get_distx(angulo1-120000,distancia1)+160,
         get_disty(angulo1-120000,distancia1)+120,
         rgb(125,125,125));
//      triangle(10,10,50,50,110,70,rgb(125,125,125));
      angulo1+=1000;
      frame;
   end
end


Process triangle(x1,y1,x2,y2,x3,y3,color);

Private
   dalt;
   baix;
   dreta;
   esquerra;
   a;
   direccio;
   
   float ax; float ay;
   float bx; float by;
   float cx; float cy;
   float dx1; float dx2; float dx3;
   float ex; float ey;
   float sx; float sy;

Begin

   if(y1>=y2 and y1>=y3) baix=y1;
   elseif(y2>=y1 and y2>=y3) baix=y2;
   else baix=y3; end
   
   if(y1<=y2 and y1<=y3) dalt=y1;
   elseif(y2<=y1 and y2<=y3) dalt=y2;
   else dalt=y3; end

   if(x1>=x2 and x1>=x3) dreta=x1;
   elseif(x2>=x1 and x2>=x3) dreta=x2;
   else dreta=x3; end
//-----------------------------------------------------   
   if(x1<=x2 and x1<=x3) esquerra=x1;
   elseif(x2<=x1 and x2<=x3) esquerra=x2;
   else esquerra=x3;
   end
//------------------------------------------------------
   if(y1<=y2 and y1<=y3)
      if(y2<=y3)
         ax=x1-esquerra; ay=y1-dalt;
         bx=x2-esquerra; by=y2-dalt;
         cx=x3-esquerra; cy=y3-dalt;
      else
         ax=x1-esquerra; ay=y1-dalt;
         bx=x3-esquerra; by=y3-dalt;
         cx=x2-esquerra; cy=y2-dalt;
      end
   end
   if(y2<=y1 and y2<=y3)
      if(y1<=y3)
         ax=x2-esquerra; ay=y2-dalt;
         bx=x1-esquerra; by=y1-dalt;
         cx=x3-esquerra; cy=y3-dalt;
      else
         ax=x2-esquerra; ay=y2-dalt;
         bx=x3-esquerra; by=y3-dalt;
         cx=x1-esquerra; cy=y1-dalt;
      end
   end
   if(y3<=y1 and y3<=y2)
      if(y1<=y2)
         ax=x3-esquerra; ay=y3-dalt;
         bx=x1-esquerra; by=y1-dalt;
         cx=x2-esquerra; cy=y2-dalt;
      else
         ax=x3-esquerra; ay=y3-dalt;
         bx=x2-esquerra; by=y2-dalt;
         cx=x1-esquerra; cy=y1-dalt;
      end
   end
   
   x=esquerra+((dreta-esquerra)/2);   
   y=dalt+((baix-dalt)/2);
   
   graph=new_map(dreta-esquerra+1,baix-dalt+1,16);
   drawing_map(0,graph);
   drawing_color(color);
   
   if(by-ay>0) dx1=(bx-ax)/(by-ay);
   else dx1=bx-ax;
   end

   if(cy-ay>0) dx2=(cx-ax)/(cy-ay);
   else dx2=0;
   end

   if(cy-by>0) dx3=(cx-bx)/(cy-by);
   else dx3=0;
   end

   sx=ax; sy=ay; ex=ax; ey=ay;

   if(dx1>dx2)
      while(sy<=by)
         draw_line(sx,sy,ex,sy);
         sy++;
         ey++;
         sx+=dx2;
         ex+=dx1;
      end
      ex=bx; ey=by;
      while(sy<=cy)
         draw_line(sx,sy,ex,sy);
         sy++;
         ey++;
         sx+=dx2;
         ex+=dx3;
      end
   else
      while(sy<=by)
         draw_line(sx,sy,ex,sy);
         sy++;
         ey++;
         sx+=dx1;
         ex+=dx2;
      end
      sx=bx; sy=by;
      while(sy<=cy)
         draw_line(sx,sy,ex,sy);
         sy++;
         ey++;
         sx+=dx3;
         ex+=dx2;
      end
   end

   drawing_color(rgb(255,0,0));
   draw_line(x1-esquerra,y1-dalt,x2-esquerra,y2-dalt);
   draw_line(x2-esquerra,y2-dalt,x3-esquerra,y3-dalt);
   draw_line(x1-esquerra,y1-dalt,x3-esquerra,y3-dalt);
   
   frame;
   unload_map(0,graph);
end
[/code]

SplinterGU

Download Lastest BennuGD Release: http://www.bennugd.org/node/2

panreyes

A ver, pero ¿quién quiere hacer triángulos si puedes hacer... rectángulos?
Es broma, karma++! :D

Drumpi

Tercer código en 7 mensajes, esto merece premio :D
Ahora, con un poco de trabajo más, te montas un renderizado 3D por soft ^^U

Nah. Buen trabajo.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Fede

Gueeeee, algo que medio entiendo.   ;D

Me uno a la ola de karmas. Por un poné.  ;D
Si quieres ser sabio, aprende a interrogar razonablemente, a escuchar con atención, a responder serenamente y a callar cuando no tengas nada que decir.

carles


Este codigo ¿cómo consumiria menos recursos? ¿dibujando los triangulos por lineas o pixel a pixel?

panreyes

Yo creo que consumiría menos si hicieses el fill del triángulo pixel a pixel

blostec

Otra de Karma, gracias Carles por la función. Saludos!

Windgate

Esa variable llamada "esquerra" me ha matado ;D

Este tipo de algoritmos ya están inventados, si es para darle utilidad real lo mejor sería ver cómo lo hicieron los frikis matemáticos en su día. En su día implementé Gouraud a partir de primitivas 2D y había que rellenar las caras de los polígonos pixel a pixel, inicialmente hice un algoritmo "a pelo" y funcionaba, pero luego seguí el algoritmo "oficial" y funcionaba ráaaapidoooo.

Por cierto, siento el offtopic, pero molaría tener el draw_line y otras primitivas en 32 bits, con suavizado de bordes en la linea. Sé que una linea en 32 bits no es una linea estrictamente porque su grosor no siempre es 1 pixel exacto, pero como añadido a nuestro querido Bennu estaría bien. Creo que ya lo comenté en su día :P
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

FreeYourMind

#9
Bueno, quiero mis karmas tambien  ;D, aqui pongo uno que hace lineas (algoritmo bresenham) y tambien triangulos usando el put_pixel. No he probado el tuyo, así que probad el mio y comprobad si tiene mas rendimineto, le dais al space para generar líneas.

PROGRAM bresenham_lines;
PRIVATE
x0,y0;
colour;
BEGIN

set_mode(320, 240, 8);

repeat

if(key(_space))
  x=rand(0,320);
  y=rand(0,200);
  x0=rand(0,320);
  y0=rand(0,200);
  colour=rand(0,255);
  draw_lines(x,y,x0,y0,colour);
end
frame;
until(key(_esc));

END

PROCESS draw_lines(xp,yp,xq,yq,colour)
PRIVATE
D=0;
dx,dy,c,M,xinc=1,yinc=1;
BEGIN
x=xp;
y=yp;
dx=xq-xp;
dy=yq-yp;

if(dx<0) xinc=-1; dx=-dx; end
if(dy<0) yinc=-1; dy=-dy; end

if(dy < dx)
  c=2*dx; M=2*dy;

  while(x!=xq)
   put_pixel(x,y,colour);
   x+=xinc; D+=M;

   if(D>dx) y+=yinc; D-=c; end
  end
else
  c=2*dy; M=2*dx;
  while(y!=yq)
   put_pixel(x,y,colour);
   y+=yinc; D+=M;

   if(D>dy) x+=xinc; D-=c; end
  end
end
put_pixel(xq,yq,colour);

END


PROCESS draw_box(x,y,x0,y0,colour)
BEGIN
draw_lines(x,y,x+x0,y,colour);
draw_lines(x,y,x,y+y0,colour);

draw_lines(x,y+y0,x+x0,y+y0,colour);
draw_lines(x+x0,y,x+x0,y+y0,colour);
end


PROCESS draw_triangle(x,y,x0,y0,x1,y1,colour)
BEGIN
draw_lines(x,y,x0,y0,colour);
draw_lines(x0,y0,x1,y1,colour);
draw_lines(x1,y1,x,y,colour);
END


EDIT: corregido, splintergu

carles


Siento ser portador de malas noticias, pero te falta un parentesis en el 3º if del proceso draw_lines.


FreeYourMind

Pues si!!! Pero me ha compilado y lo he probado!!!! O se lo ha comido al hacer aqui el paste, cosa que no creo, o Bennu esta chutando con esto!!!
Pruebalo tal cual a ver.

SplinterGU

#12
mentira free, no compila el tuyo, bueno, no compilaba, ya lo corregi...

ahora, veo que el tuyo tiene mas rendimiento que el que esta en C... :P

bueno, hay que considerar un par de cosas, la funcion en C soporta "stipple"... despues el algoritmo es el mismo, salvo inicializaciones, pero me sorprende que eso cause tanta diferencia... o habra otra cosa que no me estoy dando cuenta.

deberia implementar una funcion rapida sin stipple, para verificar como se comporta.

como sea, te has ganado un karma.

con set_fps(0,0) dibujando 1000 lineas, me dio una media de 0,98seg con tu programa en prg y 1,77seg usando las draw de bennu... :P
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Fede

Buenoooo, el karma de FreeYourMind, que lo necesita anciosamente.  ;D
Si quieres ser sabio, aprende a interrogar razonablemente, a escuchar con atención, a responder serenamente y a callar cuando no tengas nada que decir.

Drumpi

No veas, Free le ha ganado la carrera con Bennu al propio C :D :D :D Esto merece un karma ^^U
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)