Javascript 获取2矢量的角度3

Javascript 获取2矢量的角度3,javascript,math,Javascript,Math,我有两点: v1 = {x:1,y:0,z:0} v2 = {x:0,y:2,z:0} 我想计算这两点的角度。 我知道如何用2D制作,但不是3D,我有点迷路了^^ 基本上是统一的: 谢谢你的提示:3听起来像是在这个项目中,你会想找到一个向量数学参考,你可以阅读而不会发疯 ,点积v1.v2=x1*x2+y1*y2+z1*z2=|v1 |*| v2 |*cosθ,这意味着你的角度是 function angle(v1, v2) { return Math.acos(dotProduct(

我有两点:

v1 = {x:1,y:0,z:0}
v2 = {x:0,y:2,z:0}
我想计算这两点的角度。 我知道如何用2D制作,但不是3D,我有点迷路了^^

基本上是统一的:


谢谢你的提示:3

听起来像是在这个项目中,你会想找到一个向量数学参考,你可以阅读而不会发疯

,点积v1.v2=x1*x2+y1*y2+z1*z2=|v1 |*| v2 |*cosθ,这意味着你的角度是

function angle(v1, v2) {
    return Math.acos(dotProduct(v1, v2) / (length(v1) * length(v2)));
}

function dotProduct(v1, v2) {
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}

function length(v) {
    return Math.sqrt(dotProduct(v, v));
}

你可以做得更快,但如果你想要速度,那么可能就使用一个库。

听起来,对于这个项目,你会想找到一个向量数学参考,你可以阅读而不会发疯

,点积v1.v2=x1*x2+y1*y2+z1*z2=|v1 |*| v2 |*cosθ,这意味着你的角度是

function angle(v1, v2) {
    return Math.acos(dotProduct(v1, v2) / (length(v1) * length(v2)));
}

function dotProduct(v1, v2) {
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}

function length(v) {
    return Math.sqrt(dotProduct(v, v));
}

你可以让它快很多,但是如果你想提高速度,那么可以使用一个库。

使用矢量点积:

a。b=|a | b | cos$\theta$

在您的符号中:

v1.x*v2.x+v1.y*v2.y+v1.z*v2.z

|a |=sqrt(v1.x*v1.x+v1.y*v1.y+v1.z*v1.z)

|b |=sqrt(v2.x*v2.x+v2.y*v2.y+v2.z*v2.z)


将顶部结果除以底部两个结果,然后取其arccos,记住角度将以弧度为单位。

使用矢量点积:

a。b=|a | b | cos$\theta$

在您的符号中:

v1.x*v2.x+v1.y*v2.y+v1.z*v2.z

|a |=sqrt(v1.x*v1.x+v1.y*v1.y+v1.z*v1.z)

|b |=sqrt(v2.x*v2.x+v2.y*v2.y+v2.z*v2.z)


将顶部结果除以底部两个结果,然后取其arccos,记住角度将以弧度为单位。

计算两个向量之间角度的基本数学公式如下:

将a&b视为向量

a点b=abs(a)*abs(b)*cos(角度)

->cos-1((a点b)/(abs(a)*abs(b))

尽管您使用的是javascript,但进行计算的概念是相同的:我能为您做的是向您展示用c编写的Vector3类中的函数++

// -----------------------------------------------------------------------
// GetCosAngle()
// Returns The cos(Angle) Value Between This Vector And Vector V. This
// Is Less Expensive Than Using GetAngle
inline float Vector3::GetCosAngle( const Vector3 &v3, const bool bNormalized ) {
    // a . b = |a||b|cos(angle)
    // -> cos-1((a.b)/(|a||b|))

    // Make Sure We Do Not Divide By Zero
    float fMagA = Length();
    if ( fMagA <= Math::ZERO ) {
        // This (A) Is An Invalid Vector
        return 0;
    }

    float fValue = 0;

    if ( bNormalized ) {
        // v3 Is Already Normalized
        fValue = Dot(v3)/fMagA;
    }
    else {
        float fMagB = v3.Length();
        if ( fMagB <= Math::ZERO) {
            // B Is An Invalid Vector
            return 0;
        }

        fValue = Dot(v3)/(fMagA*fMagB);
    }

    // Correct Value Due To Rounding Problem
    Math::Constrain( -1.0f, 1.0f, fValue );

    return fValue;

} // GetCosAngle

// -----------------------------------------------------------------------
// GetAngle()
// Returns The Angle Between This Vector And Vector V in Radians.
//         This Is More Expensive Than Using GetCosAngle
inline float Vector3::GetAngle( const Vector3 &v3, const bool bNormalized, bool bRadians ) {
    // a . b = |a||b|cos(angle)
    // -> cos-1((a.b)/(|a||b|))

    if ( bRadians ) {
        return acos( this->GetCosAngle( v3 ) );
    }
    else {
        // Convert To Degrees
        return Math::Radian2Degree( acos( GetCosAngle( v3, bNormalized ) ) );
    }

} // GetAngle
以下是我在这些计算中使用的数学函数和值:

// -----------------------------------------------------------------------
// Length()
// Return The Length Of This Vector
inline float Vector3::Length() const {

    return sqrtf( _fX * _fX +
                  _fY * _fY +
                  _fZ * _fZ );

} // Length

// -----------------------------------------------------------------------
// Dot()
// Return The Dot Product Between This Vector And Another One
inline float Vector3::Dot( const Vector3 v3 ) const {

    return ( _fX * v3._fX + 
             _fY * v3._fY +
             _fZ * v3._fZ );
} // Dot
const float Math::PI            = 4.0f  * atan(1.0f); // tan(pi/4) = 1
const float Math::PI_INVx180    = 180.0f / Math::PI;
const float Math::ZERO          = (float)1e-7;

// -----------------------------------------------------------------------
// Constrain()
// Prevent Value From Going Outside The Min, Max Range.
template<class T>
inline void Math::Constrain( T min, T max, T &value ) {

    if ( value < min ) {
        value = min;
        return;
    }

    if ( value > max ) {
        value = max;
    }

} // Constrain

/ -----------------------------------------------------------------------
// Radian2Degree()
// Convert Angle In Radians To Degrees
inline float Math::Radian2Degree( float fRadians ) {
    return fRadians * PI_INVx180;
} // Radian2Degree
常量浮点数学::PI=4.0f*atan(1.0f);//tan(PI/4)=1 常量浮点数学::PI_INVx180=180.0f/数学::PI; 常量浮点数学::零=(浮点)1e-7; // ----------------------------------------------------------------------- //约束() //防止值超出最小、最大范围。 模板 内联无效数学::约束(T最小值、T最大值、T值和值){ 如果(值<最小值){ 值=最小值; 返回; } 如果(值>最大值){ 值=最大值; } }//约束 / ----------------------------------------------------------------------- //弧度() //将以弧度为单位的角度转换为度 内联浮点数学::弧度2度(浮点分数){ 返回fRadians*PI_INVx180; }//弧度2度

现在,正如我所说的,这些属于我的C++类,它们是在我的数学库中的一个。这是用来演示如何计算两个向量之间的夹角。

< P>两个向量之间的角度计算的基本数学公式如下:

将a&b视为向量

a点b=abs(a)*abs(b)*cos(角度)

->cos-1((a点b)/(abs(a)*abs(b))

尽管您使用的是javascript,但进行计算的概念是相同的:我能为您做的是向您展示用c编写的Vector3类中的函数++

// -----------------------------------------------------------------------
// GetCosAngle()
// Returns The cos(Angle) Value Between This Vector And Vector V. This
// Is Less Expensive Than Using GetAngle
inline float Vector3::GetCosAngle( const Vector3 &v3, const bool bNormalized ) {
    // a . b = |a||b|cos(angle)
    // -> cos-1((a.b)/(|a||b|))

    // Make Sure We Do Not Divide By Zero
    float fMagA = Length();
    if ( fMagA <= Math::ZERO ) {
        // This (A) Is An Invalid Vector
        return 0;
    }

    float fValue = 0;

    if ( bNormalized ) {
        // v3 Is Already Normalized
        fValue = Dot(v3)/fMagA;
    }
    else {
        float fMagB = v3.Length();
        if ( fMagB <= Math::ZERO) {
            // B Is An Invalid Vector
            return 0;
        }

        fValue = Dot(v3)/(fMagA*fMagB);
    }

    // Correct Value Due To Rounding Problem
    Math::Constrain( -1.0f, 1.0f, fValue );

    return fValue;

} // GetCosAngle

// -----------------------------------------------------------------------
// GetAngle()
// Returns The Angle Between This Vector And Vector V in Radians.
//         This Is More Expensive Than Using GetCosAngle
inline float Vector3::GetAngle( const Vector3 &v3, const bool bNormalized, bool bRadians ) {
    // a . b = |a||b|cos(angle)
    // -> cos-1((a.b)/(|a||b|))

    if ( bRadians ) {
        return acos( this->GetCosAngle( v3 ) );
    }
    else {
        // Convert To Degrees
        return Math::Radian2Degree( acos( GetCosAngle( v3, bNormalized ) ) );
    }

} // GetAngle
以下是我在这些计算中使用的数学函数和值:

// -----------------------------------------------------------------------
// Length()
// Return The Length Of This Vector
inline float Vector3::Length() const {

    return sqrtf( _fX * _fX +
                  _fY * _fY +
                  _fZ * _fZ );

} // Length

// -----------------------------------------------------------------------
// Dot()
// Return The Dot Product Between This Vector And Another One
inline float Vector3::Dot( const Vector3 v3 ) const {

    return ( _fX * v3._fX + 
             _fY * v3._fY +
             _fZ * v3._fZ );
} // Dot
const float Math::PI            = 4.0f  * atan(1.0f); // tan(pi/4) = 1
const float Math::PI_INVx180    = 180.0f / Math::PI;
const float Math::ZERO          = (float)1e-7;

// -----------------------------------------------------------------------
// Constrain()
// Prevent Value From Going Outside The Min, Max Range.
template<class T>
inline void Math::Constrain( T min, T max, T &value ) {

    if ( value < min ) {
        value = min;
        return;
    }

    if ( value > max ) {
        value = max;
    }

} // Constrain

/ -----------------------------------------------------------------------
// Radian2Degree()
// Convert Angle In Radians To Degrees
inline float Math::Radian2Degree( float fRadians ) {
    return fRadians * PI_INVx180;
} // Radian2Degree
常量浮点数学::PI=4.0f*atan(1.0f);//tan(PI/4)=1 常量浮点数学::PI_INVx180=180.0f/数学::PI; 常量浮点数学::零=(浮点)1e-7; // ----------------------------------------------------------------------- //约束() //防止值超出最小、最大范围。 模板 内联无效数学::约束(T最小值、T最大值、T值和值){ 如果(值<最小值){ 值=最小值; 返回; } 如果(值>最大值){ 值=最大值; } }//约束 / ----------------------------------------------------------------------- //弧度() //将以弧度为单位的角度转换为度 内联浮点数学::弧度2度(浮点分数){ 返回fRadians*PI_INVx180; }//弧度2度

现在我说这些属于我的两个C++类,它们是在我的数学库中的一个。这是用来演示如何计算两个向量之间的夹角。

< P>使用<代码> ACOS(Ab/((a a,b b))< /C> >当角度小(或接近180度)时不稳定。。在2D或3D情况下,解决方案是使用
atan2(,)

对于3D,计算点积和叉积的长度:

使用
acos(a.b/(|a | | b |))
在角度较小(或接近180度)时是不稳定的。在2D或3D情况下,解决方案是使用
atan2(,)

对于3D,计算点积和叉积的长度:


坦克我要试试那个:)坦克我要试试那个:)是的,这是涉及到的基本数学,但在使用处理器进行计算时缺少几个步骤:必须检查以确保向量3不是0向量,否则将被0除,并且在计算cos角度时,由于舍入误差,仍然需要限制值。除此之外,还需要重新定位!是的,这是涉及的基本数学,但使用处理器进行计算时缺少几个步骤:必须检查以确保向量3不是0向量,否则将被0除,并且在计算cos角时,由于舍入误差,仍然需要限制值。除了你是正确的!