Search code examples
c++openglfractals

Creating a fractal tree in opengl


Having a little trouble creating a fractal in opengl. Here is my current code

void generateTree(){
  Point3f startPoint({0.0f,0.0f,0.0f});
  Point3f endPoint({1.0f,0.0f,0.0f});
  float rotation = 90.0f;
  glutWireSphere(0.05, 4, 4);
  _generateTreeBranches(startPoint,1.0f,rotation,0);
}

void _generateTreeBranches(const Point3f& newPosition,
                       float length,
                       float rotation,
                       const int depth)
{
  if(depth > MAX_DEPTH) return;
  cout << "at depth = " << depth << endl;


  if(depth == 0){
      glColor3f(1.0f,1.0f,1.0f);
  }else if(depth == 1){
      glColor3f(1.0f,0.0f,0.0f);
  }else{
      glColor3f(0.0f,1.0f,0.0f);
  }

  glTranslatef(newPosition.x,newPosition.y,newPosition.z);
  glRotatef(rotation, 0.0f, 0.0f, 1.0f);
  drawLine(length);
  glRotatef(-rotation, 0.0f, 0.0f, 1.0f);
  glTranslatef(-newPosition.x,-newPosition.y,-newPosition.z);



  const float newLength = length * BRANCH_LENGTH_DECREASE_FACTOR;
  int nextDepth = depth + 1;
  Point3f nextPosition = {newPosition.x+length, newPosition.y, newPosition.z};

  float leftRotation = rotation + CHILD_BRANCH_ANGLE * nextDepth;
  _generateTreeBranches(nextPosition,newLength,leftRotation,nextDepth);

  float rightRotation = rotation - CHILD_BRANCH_ANGLE * nextDepth;
  _generateTreeBranches(nextPosition,newLength,rightRotation,nextDepth);

}

The positioning isn't correct, although the rotation seems to be right. The new branches arent' being draw starting at the end point of the parent's branch. Can someone help me on fixing this problem. Check out the full code here


Solution

  • The formula for nextPosition is incorrect as it didn't factor in the direction which the current branch is facing

     Point3f nextPosition = {newPosition.x+length, newPosition.y, newPosition.z};
    

    It should be something like this (please check exactly):

    Point3f nextPosition = {newPosition.x+length*cos(rotation), newPosition.y+length*sin(rotation), newPosition.z};
    

    Also, please use glLoadIdentity() to reset the matrix immediately like this:

    glTranslatef(newPosition.x,newPosition.y,newPosition.z);
    glRotatef(rotation, 0.0f, 0.0f, 1.0f);
    drawLine(length);
    glLoadIdentity();
    

    It will be much clearer than what you are trying to do.