难以计算圆上一点的角度

时间:2013-11-12 19:14:27

标签: c++ visual-c++ geometry

我正在写一个函数的几何有点麻烦。我有一个包含各种精灵的类。这个容器类需要能够移动,旋转和缩放,同时保持所有子精灵的相对位置,旋转和比例不变。

旋转容器时遇到问题。由atan2计算的角度似乎是随机的。我写了一个简单的控制台应用程序,它在我正在使用的函数后面执行并输出数学(很难正确显示代码,因为它依赖于各种外部源代码)。我这样做是为了确保它不是代码的另一部分导致我的错误。但我的结果与控制台应用程序相同。这是代码(它是独立的。你可以轻松运行它)

#include<math.h>
#include<iostream>

using namespace std;

  int main()
    {
        float containerX = 0;
        float containerY = 0;

        float childX = 10;
        float childY = 0;

        for(int i = 0; i <= 360; i += 36)
        {
            float radius = sqrt(pow(containerX - childX, 2) + pow(containerY - childY, 2));
            float angle = atan2 (containerY - childY, containerX - childX);

            float newAngle = angle + (i / 180.0 * 3.14);

            childX = containerX + radius * cos(newAngle);
            childY = containerY + radius * sin(newAngle);

            std::cout << "New angle: " << newAngle * 180.0 / 3.14 << " New Position: " << childX << ", " << childY << std::endl;

        }

        while(1!=2) {} // This line is so I can read the console output

        return 0;
    }

我的输出如下:

New angle: 180.091 New Position: -10, -8.74228e-007
New angle: 36 New Position: 8.09204, 5.87528
New angle: -72.0913 New Position: 3.08108, -9.51351
New angle: 216 New Position: -8.10139, -5.86238
New angle: 179.909 New Position: -9.99995, 0.0318542
New angle: 179.817 New Position: -9.99988, 0.0477804
New angle: 215.726 New Position: -8.12931, -5.8236
New angle: 287.635 New Position: 3.00522, -9.53775
New angle: 395.543 New Position: 8.15704, 5.78469
New angle: 179.27 New Position: -9.99897, 0.143339
New angle: 359.178 New Position: 9.99846, -0.175189

我知道这个问题与我用atan2计算角度有关,因为如果我只是将i转换为弧度(我以36为增量迭代0度和360度)并将其传递给cos和sin,我在圆圈周围得到了积分。如果我使用我的“newAngle”变量,我会在圆周上得到随机点(左下角,右上角,左下角,左边的圆圈,右边的圆圈等)

感谢您阅读本文。对此,我真的非常感激。我完全陷入了困境。任何帮助都会很棒。

3 个答案:

答案 0 :(得分:2)

  

float angle = atan2(containerY - childY,containerX - childX);

成功

  

float angle = atan2(childY - containerY,childX - containerX);

正如最初所写的那样,您在每次迭代时都会在旋转中心周围翻转子坐标(换句话说,添加额外的180度偏移)。如果你根本不调整角度,你可以很容易地看到这个:float newAngle = angle;。你的坐标会在-10到10之间振荡。

答案 1 :(得分:2)

float angle = atan2 (containerY - childY, containerX - childX);
float newAngle = angle + (i / 180.0 * 3.14);

在第一行中,您将获得新的角度。在第二行中,您不只是添加36度,而是添加i度,因此在每次迭代中,代码都会向 new 角度添加一个增加的角度已经在增加,因此是零星的行为。

两种不同的解决方案:

1)用

替换第一行
float angle = 3.14159; // allow the loop to add to it

2)将行中的i更改为36

float newAngle = angle + (36 / 180.0 * 3.14);

不要两者都做!选择一个。

答案 2 :(得分:0)

我在评论中暗示了这一点,但这就是你如何解决问题以解决问题:http://ideone.com/nTGXuv

#include <cmath>
#include <iostream>
#include <utility>

std::pair<float, float> rotate(std::pair<float, float> origin, std::pair<float, float> start, unsigned int degrees)
{
    std::pair<float, float> diff = std::make_pair(start.first - origin.first, start.second - origin.second);
    float currentAngle = ::atan2(diff.second, std::abs(diff.first));
    float newAngle = currentAngle + (degrees / 180.0 * 3.1415926539);
    float radius = std::sqrt(diff.first * diff.first + diff.second * diff.second);
    float cosAngle = ::cos(newAngle);
    float sinAngle = ::sin(newAngle);
    float x = origin.first + radius * cosAngle;
    float y = origin.second + radius * sinAngle;
    return std::make_pair(x, y);
}

int main() 
{
    std::pair<float, float> origin = std::make_pair(0.0, 0.0);
    std::pair<float, float> start = std::make_pair(1.0, 0.0);
    const unsigned int degrees = 45;
    for (unsigned int i = 0; i < 360; i += degrees)
    {
        std::pair<float, float> newPos = rotate(origin, start, i);
        std::cout << "Rotated to " << i << " degrees: (" << newPos.first << ", " << newPos.second << ")" << std::endl;
    }
    return 0;
}