获取两点之间的角度并以该角度围绕另一个点旋转一个点 - C++

问题描述 投票:0回答:2

我基本上是在尝试根据贝塞尔曲线上的点创建二维线。 贝塞尔曲线的所有点都放置得很好,一切看起来都井然有序。 从这些点开始,我在 z 轴上创建另外 2 个点,它们将作为线的边界:

    glm::vec3    p1 = pos[i];
    p1.z = p1.z + (size / 2);

    glm::vec3    p2 = pos[i];
    p2.z = p2.z - (size / 2);

然后我通过围绕主要点旋转这些点来更改它们的位置:

pm 是移动点绕固定点pf

旋转
    glm::vec3   rotP = glm::vec3(0.0f, 0.5f, 0.0f);

    float   co = cos(angle);
    float   si = sin(angle);

    // CLOCKWISE
    rotP.x = (pf.x - pm.x) * co + (pf.z - pm.z) * si + pm.x;
    rotP.z = -(pf.x - pm.x) * si + (pf.z - pm.z) * co + pm.z;

angle 是贝塞尔曲线上向后点和向前点之间的角度:

depForward 是 x, glm::vec3(1.0f, 0.0f, 0.0f)

    glm::vec3 normForwardUnit = normalize(p2 - p1);
    float angle = (acos(dot(depForward, normForwardUnit)));

我遇到的问题是旋转错误。我的一些线条是正确的,但它似乎取决于线条的方向。

示例不正确 正确示例

我认为问题出在轮换的格式上,但我仍然无法理解。 我尝试将角度标准化为不同的范围:

//0 to 2PI
    if (angle < 0) { angle += 2 * PI; }
//-PI to PI
    if (angle > PI)        { angle -= 2 * PI; }
    else if (angle <= -PI) { angle += 2 * PI; }

其他计算角度的方法:

    float angle = atan2(p2.z - p1.z, p2.x - p1.x);

逆时针旋转点:

//COUNTER CLOCKWISE
    rotP.x = (pf.x - pm.x) * co - (pf.z - pm.z) * si + pm.x;
    rotP.z = (pf.x - pm.x) * si + (pf.z - pm.z) * co + pm.z;
c++ geometry rotation glm-math radians
2个回答
1
投票

如果有人需要,这里是 paddy 方法的实现。 您可以使用 backP 和 nextP 之间的点而不是 midPoint 来放置新点。

backP 和 nextP 是 b 曲线的前后点

  // VEC FORWARD VECTOR
  glm::vec3 forwardVec = normalize(backP - nextP);

  //PERPENDICULAR VEC
  glm::vec3 perpVec = cross(forwardVec, glm::vec3(0.0f, 1.0f, 0.0f));
  perpVec = normalize(perpVec);

  //MID POINT
  glm::vec3 midP = midPoint(backP, nextP);

  // GEN POINTS
  glm::vec3 p1 = midP + (width * perpVec);
  glm::vec3 p2 = midP - (width * perpVec);

0
投票

我认为你绝对应该看看这个:

如果您坚持自己的方式,则不需要使用任何角度或旋转......

您有从多项式曲线中采样的线

p0,p1
,因此:

tangent = p1-p0

但是,最好有更好的切线近似值,因此可以通过曲线的一阶导数来获取它,或者使用 2 条后续线

(p0,p1) , (p1,p2)
那么点
p1
处的切线是:

tangent = p2-p1

欲了解更多信息,请参阅:

现在取

bitangent
(相机的z轴,可以从相机矩阵中提取)并使用叉积得到
normal

normal = normalize(cross(tangent,binormal))

现在你只需将

p1
替换为正常即可:

p1'  = p1 + 0.5*curve_thickness*normal
p1'' = p1 - 0.5*curve_thickness*normal

对曲线的所有点执行相同的操作...之后,您只需使用

p'
p''
点渲染四边形...

但是,使用这种方法,您可能会遇到可能需要进一步调整的问题,请参阅:

© www.soinside.com 2019 - 2024. All rights reserved.