首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >计算中间向量角度

计算中间向量角度
EN

Stack Overflow用户
提问于 2013-04-21 21:50:33
回答 1查看 472关注 0票数 0

我有一个椭圆粒子系统,我试图计算每个粒子的长轴和距离下一个粒子中心的距离的向量之间的角度。我希望这张照片能很好地说明问题。

在这个例子中,我在(0,0)和(10,-10)处初始化了两个粒子。每个粒子相对于笛卡尔系统的角度是45度。所以这两个是平行的。我想计算我在图片中标记为90度角的角度。

为此,我使用点积创建了这个函数:

代码语言:javascript
运行
复制
    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)做了一个方法:

代码语言:javascript
运行
复制
    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度,这是不好的。任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-21 22:20:29

很难确定,根据你的描述,但是...试试这个:

代码语言:javascript
运行
复制
double x2, y2, theta, omega;

theta = current->getTheta();

x2 = next->getCurrX() - current->getCurrX();
y2 = next->getCurrY() - current->getCurrY();

omega = atan2(y2,x2) - theta;
cout << omega << endl;
return omega;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16131832

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档