Autor Tema: Funcion para dibujar triangulos  (Leído 13010 veces)

carles

  • Jr. Member
  • **
  • Mensajes: 50
  • Karma: 20
Funcion para dibujar triangulos
« en: Junio 12, 2010, 09:22:16 am »

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

  • Hero Member
  • *****
  • Mensajes: 12975
  • Karma: 379
Re: Funcion para dibujar triangulos
« Respuesta #1 en: Junio 12, 2010, 01:48:32 pm »
acumulando karmas!

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

panreyes

  • Administrator
  • *****
  • Mensajes: 2277
  • Karma: 82
    • panreyes.com
Re: Funcion para dibujar triangulos
« Respuesta #2 en: Junio 12, 2010, 02:51:26 pm »
A ver, pero ¿quién quiere hacer triángulos si puedes hacer... rectángulos?
Es broma, karma++! :D

Drumpi

  • Hero Member
  • *****
  • Mensajes: 6466
  • Karma: 168
  • Odio el periodo "entre proyectos"
    • La web de Drumpi
Re: Funcion para dibujar triangulos
« Respuesta #3 en: Junio 12, 2010, 03:47:25 pm »
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

  • Hero Member
  • *****
  • Mensajes: 1532
  • Karma: 71
  • Buen ambiente, buen karma.
Re: Funcion para dibujar triangulos
« Respuesta #4 en: Junio 12, 2010, 03:51:28 pm »
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

  • Jr. Member
  • **
  • Mensajes: 50
  • Karma: 20
Re: Funcion para dibujar triangulos
« Respuesta #5 en: Junio 13, 2010, 09:17:44 am »

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

panreyes

  • Administrator
  • *****
  • Mensajes: 2277
  • Karma: 82
    • panreyes.com
Re: Funcion para dibujar triangulos
« Respuesta #6 en: Junio 13, 2010, 09:29:41 am »
Yo creo que consumiría menos si hicieses el fill del triángulo pixel a pixel

blostec

  • Hero Member
  • *****
  • Mensajes: 760
  • Karma: 22
Re: Funcion para dibujar triangulos
« Respuesta #7 en: Junio 13, 2010, 11:35:01 am »
Otra de Karma, gracias Carles por la función. Saludos!

Windgate

  • Hero Member
  • *****
  • Mensajes: 2930
  • Karma: 124
    • TRINIT Asociación de Informáticos de Zaragoza
Re: Funcion para dibujar triangulos
« Respuesta #8 en: Junio 13, 2010, 03:43:22 pm »
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

  • Hero Member
  • *****
  • Mensajes: 5731
  • Karma: 129
    • GECA soft
Re: Funcion para dibujar triangulos
« Respuesta #9 en: Junio 14, 2010, 07:10:11 pm »
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.

Código: [Seleccionar]
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
« última modificación: Junio 15, 2010, 03:05:14 pm por SplinterGU »

carles

  • Jr. Member
  • **
  • Mensajes: 50
  • Karma: 20
Re: Funcion para dibujar triangulos
« Respuesta #10 en: Junio 15, 2010, 10:07:09 am »

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


FreeYourMind

  • Hero Member
  • *****
  • Mensajes: 5731
  • Karma: 129
    • GECA soft
Re: Funcion para dibujar triangulos
« Respuesta #11 en: Junio 15, 2010, 10:46:37 am »
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

  • Hero Member
  • *****
  • Mensajes: 12975
  • Karma: 379
Re: Funcion para dibujar triangulos
« Respuesta #12 en: Junio 15, 2010, 03:37:57 pm »
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
« última modificación: Junio 15, 2010, 03:41:58 pm por SplinterGU »
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Fede

  • Hero Member
  • *****
  • Mensajes: 1532
  • Karma: 71
  • Buen ambiente, buen karma.
Re: Funcion para dibujar triangulos
« Respuesta #13 en: Junio 15, 2010, 05:04:49 pm »
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

  • Hero Member
  • *****
  • Mensajes: 6466
  • Karma: 168
  • Odio el periodo "entre proyectos"
    • La web de Drumpi
Re: Funcion para dibujar triangulos
« Respuesta #14 en: Junio 15, 2010, 05:24:04 pm »
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)