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角时,由于舍入误差,仍然需要限制值。除了你是正确的!