Page 1 of 1

Tree Generator

Posted: Tue Nov 18, 2014 6:34 pm
by applePi
i have stumbled across this beautiful tree generating algorithm, it produce a static picture , i have converted it to purebasic to be able to rotate it using the classic OpenGL with the gorgeous PB OpenGLGadget
the code draw a line between every 2 points in the tree, all the structured data are stored in an array , then we use glDrawArrays_(#GL_LINES, 2 * i, 2) to draw every line alone with its special color and thickness.
to be honest i don't like the recursive functions, it is like a hurricane damaging the brain. but this is what is available.
a future project is to make a real tree with 3d thickness, don't know how to do that but i guess will be more suitable in PB ogre engine.
notes:
line 18: depth = 8 ; height of the tree, change it down as you want, but change it up with care since it will slow the machine too much.
line 26: glTranslatef_(0, -200, -400) change -400 to -300 and the tree will be closer
change -200 to -100 and the tree will go up.
to change the color look line 77 and line 81
Image

Code: Select all

Structure Point3D
  x.f
  y.f
  z.f
  d.f ; thickness of the lines
  r.f ; red
  g.f ;green
  b.f ;blue
EndStructure

Define event, quit
Declare tree(x1.l, y1.l, angle.f, d.l)

OpenWindow(0, 0, 0, 800, 600, "OpenGL demo .. recursive Tree inside 3D env")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 20, 10, WindowWidth(0)-40 , WindowHeight(0)-20)

depth = 8 ; height of the tree
Global NbX = Pow(2, depth) ; number of tree lines (tree branches)
Global NbZ = 1

Global Dim Point3D.Point3D(NbX,NbZ) ; array to store x,y color for every line of the tree
                                     ; every line have only 2 points at its terminals
glLoadIdentity_();
gluPerspective_(90.0, 800/600, 1.0, 1500.0)
glTranslatef_(0, -200, -400)
glEnable_(#GL_DEPTH_TEST)

  rot.f = 1 ; rotation speed, try also 3
  tree(0, 0, 90, depth) ; call the tree proc to fill the structured array with points data
    
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  Repeat
  
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glRotatef_(rot, 0, 1, 0);
 
  glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
   
  glVertexPointer_(3, #GL_FLOAT,SizeOf(Point3D),Point3D(0,0)) ; pointer to the first point in the structured array
  glColorPointer_(3, #GL_FLOAT, SizeOf(Point3D), @Point3D(0,0)\r) ; pointer to the first point red color
    
  For i = 0 To NbX

    glLineWidth_(Point3D(i,0)\d); call the thickness data of every line
    glDrawArrays_(#GL_LINES, 2 * i, 2) ;plot one line from point with index 2*i To the Next point, ie plot 2 points only
    
  Next
  
  glDisableClientState_(#GL_VERTEX_ARRAY);
  glDisableClientState_(#GL_COLOR_ARRAY)
  
  Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
  Until event = 0 Or quit = #True
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  ;Delay(1)
Until quit = #True

Procedure tree(x1.l, y1.l, angle.f, d.l)
  Static N
  x2.l: y2.l
   If d > 0
    
    x2 = x1 + Cos(Radian(angle)) * d * Random(12,5)
    y2 = y1 + Sin(Radian(angle)) * d * Random(12,5)
   
    ;storing x,y, color for the first point of the line 
    Point3D(N,0)\x = x1
    Point3D(N,0)\y = y1
    Point3D(N,0)\d = d  ;thickness of the line
    Point3D(N,0)\r = (255-d*40)/255 :Point3D(N,0)\g = (100-d)/255 :Point3D(N,0)\b = 70/255 
    ; storing x,y, color for the second point of the line
    Point3D(N,1)\x = x2
    Point3D(N,1)\y = y2
    Point3D(N,1)\r = (255-d*40)/255 :Point3D(N,1)\g = (100-d)/255 :Point3D(N,1)\b = 70/255 
    N+1 ; increase array index by 1
        
    d-1
    
    tree(x2, y2, angle-20, d)
    tree(x2, y2, angle+20, d)
    
  EndIf
  ;Debug N ; total number of braches after call tree procedure
  
EndProcedure


 

Re: Tree Generator

Posted: Tue Nov 18, 2014 10:08 pm
by juror
Most impressive.

Thanks for sharing :D

Re: Tree Generator

Posted: Wed Nov 19, 2014 7:33 am
by davido
@applepi,

Another fine example. Thank you for sharing. :D

Thank too, for the tips on changing the parameters. Even tried speed of 59.

Re: Tree Generator

Posted: Wed Nov 19, 2014 9:49 am
by applePi
thanks juror and davido,
davido, try also to change number 20 to 30 in line 86-87
tree(x2, y2, angle-20, d)
tree(x2, y2, angle+20, d)

and you will get a more bent tree, change it to 10 and will get a narrower tree
change one line to 20 and the other to 30 and will get non symmetrical tree
** and in the lines:
x2 = x1 + Cos(Radian(angle)) * d * Random(12,5)
y2 = y1 + Sin(Radian(angle)) * d * Random(12,5)

replace Random(12,5) with a fixed number like 10 and you will have a more symmetrical tree

Re: Tree Generator

Posted: Thu Nov 20, 2014 2:11 pm
by Kwai chang caine
Nice :shock:
Works great, thanks for sharing 8)