我有一个椭圆粒子系统,我正在尝试计算每个粒子的主轴与距下一个粒子中心的距离矢量之间的角度。这张照片应该很好地说明,我希望。
在这个例子中,我在 (0,0) 和 (10,-10) 处初始化了两个粒子。每个粒子相对于笛卡尔系统的角度是 45 度。所以这两个是平行的。我想计算我在图片中标记为 90 度角的角度。
为此,我使用点积制作了这个功能:
double temp = 0;
double result = 0;
double cosPhi = 0;
double dotProd = 0;
double cosTheta = cos(current->getTheta());
// If Theta = PI/2, there is a tiny difference between this rounded value
// and the exact value of PI/2 due to double precision representation. This
// gives cos(PI/2) = 6*10^-17 instead of 0. So, manually set cos(PI/2) = 0.
if(almostEqual(cosTheta,0))
cosTheta = 0;
double cellLengthX = current->getLength()*cosTheta;
double cellLengthY = current->getLength()*sin(current->getTheta());
double dist = Distance(current, next);
if(dist == 0)
return 0.0;
//cout << "Dist " << dist << endl;
// calculate the vector of distance
// next - current, because the end of the vector is the next cell,
// while the start of the vector is the current cell.
double distX = next->getCurrX() - current->getCurrX();
double distY = next->getCurrY() - current->getCurrY();
//cout <<"DistX " << distX <<" DistY " << distY << endl;
// Dot product
dotProd = cellLengthX*distX + cellLengthY*distY;
//cout << "DotP " << dotProd << endl;
// angle from formula : vector_a*vector_b = |a||b|cos(phi)
cosPhi = dotProd/(current->getLength()*dist);
cout << "aCos " << acos(cosPhi) << endl;
if(cosPhi == 1) // 0 degrees
{
return 0;
}
else if(cosPhi == -1) // 180 degrees
{
return M_PI;
}
else if(cosPhi == 0) // 90 or 270 degrees
{
if(distX>0 || distY>0)
return M_PI_2; // 90
else
return 3*M_PI_2; // 270
}
else if(-distX<=0 && -distY <0) // 1st quadrant -distX<=0
{
//cout << "Angle 1st :" << acos(cosPhi) << endl;
return acos(cosPhi);
}
else if(-distX>=0 && -distY >0) // 3rd quadrant -distX>=0
{
temp = acos(cosPhi);
result = M_PI_2 + temp;
//cout << "Angle 3rd :" << result << endl;
return result;
}
else if(-distX >0 && -distY <=0) // 2nd quadrant -distY <=0
{
//cout << "Angle 2nd :" << acos(cosPhi) << endl;
return acos(cosPhi);
}
else if(-distX <0 && -distY >=0) // 4th quadrant -distY >=0
{
temp = acos(cosPhi);
result = 3*M_PI_2 + temp;
//cout << "Angle 4th :" << result << endl;
return result;
}
这种方法原则上是有效的,但是当我判断在哪个象限分配acos(cosPhi)
. 正如我从其他人那里读到的那样(并发现自己)存在问题,acos
因为您不知道在哪个象限中分配最终角度。
所以我用atan2(y,x)做了一个方法:
double x1, y1, x2, y2, phi1, phi2, theta, omega;
omega = 0;
theta = current->getTheta();
phi1 = 0;
phi2 = 0;
x1 = current->getLength()*cos(theta);
y1 = current->getLength()*sin(theta);
x2 = next->getCurrX() - current->getCurrX();
y2 = next->getCurrY() - current->getCurrY();
//phi1 = atan2(y1,x1);
//phi2 = atan2(y2,x2);
omega = atan2(y2-y1,x2-x1);//phi2 - phi1;
cout << phi1 << " " << phi2 << " " << omega << endl;
return omega;
但是我得到的是第一个粒子的-90度(我想没关系)和第二个粒子的-180度,这是不行的。任何帮助将非常感激。