计算两条线之间3D角度的点

时间:2014-02-19 10:43:08

标签: opengl math vector 3d angle

我正在尝试计算角度(圆弧段)上的多个点,以便我可以将其存储为Vector3的VBO并在OpenGL中渲染。

3D angle

想象一下虚线上的每个点都是我想要计算的坐标

我知道我可以使用点积找到角度的大小,并且在2维中,我将能够仅使用该角度的sin和cos来计算角度上的点。但是我如何在三维中应用它?

我想也许我应该把角度分成组件,但后来不确定如何计算那种情况下的大小。

那么计算这些点的最佳方法是什么,我该怎么做?

我正在使用C#,但当然是伪代码或只是方法。

3 个答案:

答案 0 :(得分:1)

标准化并缩放两个向量,然后在它们之间进行分类

slerp代表球面线性插值,主要用于四元数,但在此也有效

vec3 slerp(vec3 a, vec3 b, float t){
    float dotp = dot(a,b);
    if (dotp > DOT_THRESHOLD) {
        // If the inputs are too close for comfort, linearly interpolate
        // and normalize the result to avoid division by near 0

        vec3 result = v0 + t*(v1 – v0);
        result.normalize();
        return result;
    }
    float theta = acos(dotp);
    return (sin(theta*(1-t))*a + sin(theta*t)*b)/sin(theta);
}

答案 1 :(得分:0)

诀窍是计算点,好像你的两个向量是单位向量。只是半圈。但是然后不要把它写成(x,y)=(0,0,1)* x +(0,1,0)* y ......只需将你的两个红色和绿色向量作为一个新的基础。

计算你的2d x,y圆点。然后3d点是redvector * x + greenvector * y。

答案 2 :(得分:0)

这是一个用于C#项目的C ++ DLL(已测试但角度不均匀,但只要向量具有大小,就没有除零):

enter image description here

用法:

 [DllImport("angle.dll")]
        extern static void anglePoints(
                                                  float x1,
                                                  float y1,
                                                  float z1,
                                                  float x2,
                                                  float y2,
                                                  float z2,
                                                  float [] points
                                                  );

DLL的İnside:

class float3
{
public:
    float x,y,z;
    float3(float X, float Y, float Z)
    {
        x=X; y=Y; z=Z;
    }

    float3 sub(float X, float Y, float Z)
    {
        float3 tmp(0,0,0);
        tmp.x=x-X;
        tmp.y=y-Y;
        tmp.z=z-Z;
        return tmp;
    }

    float3 sub(float3 b)
    {
        float3 tmp(0,0,0);
        tmp.x=x-b.x;
        tmp.y=y-b.y;
        tmp.z=z-b.z;
        return tmp;
    }

    float3 add(float3 b)
    {
        float3 tmp(0,0,0);
        tmp.x=x+b.x;
        tmp.y=y+b.y;
        tmp.z=z+b.z;
        return tmp;
    }

    void normalize()
    {
        float r=sqrt(x*x+y*y+z*z);
        x/=r;
        y/=r;
        z/=r;
    }

    void scale(float s)
    {
        x*=s;y*=s;z*=s;
    }

    void set(float3 v)
    {
        x=v.x;y=v.y;z=v.z;
    }

};


extern "C" __declspec(dllexport) void anglePoints(
                                                  float x1,
                                                  float y1,
                                                  float z1,
                                                  float x2,
                                                  float y2,
                                                  float z2,
                                                  float * points
                                                  )
{
    float3 A(x1,y1,z1);
    float3 B(x2,y2,z2);
    float3 tmp(0,0,0);
    float3 diff(0,0,0);

    for(int i=0;i<10;i++)
    {
        tmp.set(A);
        diff.set(B.sub(A));
        diff.scale(0.1*((float)i)); // simple and not efficient :P
        diff.set(diff.add(tmp));
        diff.normalize();           // normalized values so you can
        points[i*3+0]=diff.x;       // simply use them
        points[i*3+1]=diff.y;
        points[i*3+2]=diff.z;

    }

}

示例:

        float[] tmp = new float[30];
        anglePoints(0,1,1,10,10,10,tmp);
        for (int i = 0; i < 30; i++)
        {
            Console.WriteLine(tmp[i]);
        }

输出:

0              // starts as 0,1,1 normalized
0,7071068
0,7071068

0,34879
0,6627011
0,6627011

0,4508348
0,6311687
0,6311687

0,4973818
0,6134375
0,6134375

0,5237828
0,6023502
0,6023502

0,540738
0,5948119
0,5948119

0,5525321
0,5893675
0,5893675

0,5612046
0,5852562
0,5852562

0,5678473
0,5820435
0,5820435

0,5730973    //ends as 10,10,10 but normalized
0,579465
0,579465