沿3d曲线渲染圆圈

时间:2015-10-28 21:46:43

标签: c++ opengl computational-geometry curve glm-math

我试图在3d曲线的每个点周围渲染圆圈。基本上尝试为曲线创建管状结构。但是圆圈的方向是错误的,如图所示。下面是我计算frenet帧后对圆形对象的Model矩阵的计算。我哪里错了? 作为参考,绿线是正切,蓝色是正常,红色是正常。

view 1 view 2

Frenet Frame Calculations

glm::vec3 pointback = curve_points[i-1];
glm::vec3 pointmid = curve_points[i];
glm::vec3 pointforward = curve_points[i+1];

glm::vec3 forward_tangent_vector =  glm::vec3(glm::normalize(pointforward - pointmid)) ;
glm::vec3 backward_tangent_vector = glm::vec3(glm::normalize(pointmid - pointback)) ;

glm::vec3 second_order_tangent = glm::normalize(forward_tangent_vector - backward_tangent_vector);

glm::vec3 binormal = glm::normalize(glm::cross(forward_tangent_vector, second_order_tangent));

glm::vec3 normal = glm::normalize(glm::cross(binormal, forward_tangent_vector));

Model Matrix for Circle calculations

glm::mat3 tbn = glm::mat3(forward_tangent_vector,binormal,normal);

glm::vec3 normal_axis = glm::vec3(0, 1, 0);
//normal_axis = forward_tangent_vector;

glm::vec3 circleNormal = glm::normalize(tbn * normal_axis);
glm::vec3 rotationAxis = glm::cross(normal_axis, circleNormal);
float rotationAngle = glm::acos(glm::dot(normal_axis, circleNormal));

R = glm::rotate(R, glm::degrees(rotationAngle), rotationAxis);

T = glm::translate(T, pointmid);

glm::mat4 Model = T*R;

1 个答案:

答案 0 :(得分:3)

最简单的方法是使用Frenet-Serret帧,通常称为TBN帧或TBN矩阵。以下是:

  1. 在曲线上取样两点。让他们称呼他们"当前"和" next"。
  2. 按如下方式构建Frenet框架:

    vec3 T = normalize( next - current );
    vec3 B = normalize( cross( T, next + current ) );
    vec3 N = normalize( cross( B, T ) );
    
  3. 计算您的2D圆圈,类似于:

    float x = cos( angle );
    float y = sin( angle );
    
  4. 现在,使用Frenet框架计算正确的方向:

    vec3 tangent = T;
    vec3 normal = normalize( B * x + N * y );
    vec3 vertex = current + B * x + N * y; // note: not normalized!
    
  5. 这里有一个易于理解的解释: http://www.blackpawn.com/texts/pqtorus/