2012-10-30 44 views
1

在opengl中创建一个分形有点麻烦。这是我目前的代码在opengl中创建一个分形树

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); 

} 

虽然旋转似乎是正确的,但定位不正确。新分支不是从父分支的终点开始绘制的。有人可以帮我解决这个问题。退房的完整代码here

+0

我可以看到你依靠堆叠glTranslatef和glRotatef函数通过递归调用来实现你的分形树。这很糟糕,因为最终的结果并不总是很明显,而且很容易出错。我建议你在数学上执行当前分支的旋转和平移计算,并在glPushMatrix/glPopMatrix的每个分支上应用一对glRotatef + glTranslatef,以将其重置为下一分支。更少的混淆和更数学的声音。 – ksming

+0

嗨,感谢您的帮助。我试图避免手动计算,只是让opengl做的工作,但对于这种情况下,它可能更好,更容易阅读,如果我手动执行它 – dchhetri

回答

1

为下一位置的公式不正确,因为它没有在方向因子,其当前分支正面临

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

应该是这样的(请准确):

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

另外,请使用glLoadIdentity(),以矩阵立即复位这样的:

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

它会比你想要做的更清晰。

+0

嘿谢谢你的帮助,你能解释为什么我会用glLoadIdentity代替抵消了以前的转型?我也需要推动/弹出当前堆栈中的矩阵? – dchhetri