0

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

旋转容器时遇到问题。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”变量,我会在圆的圆周上得到随机点(左下角、右下角、左下角附近、圆的左边、圆的右边等)

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

4

3 回答 3

2

浮动角度 = atan2 (containerY - childY, containerX - childX);

做了

浮动角度 = atan2 (childY - containerY, childX - containerX);

如最初所写,您在每次迭代时围绕旋转中心翻转子坐标(换句话说,添加额外的 180 度偏移)。如果您根本不调整角度,您可以很容易地看到这一点:float newAngle = angle;. 您的坐标将在 -10 到 10 之间波动。

于 2013-11-12T20:46:18.380 回答
2
float angle = atan2 (containerY - childY, containerX - childX);
float newAngle = angle + (i / 180.0 * 3.14);

在第一行,你得到了新的角度。在第二行中,您不只是添加 36 度,而是添加度数,因此在每次迭代中,代码都会向本身已经在增加的i角度添加增加的角度,因此会出现零星的行为。

两种不同的解决方案:

1)将第一行替换为

float angle = 3.14159; // allow the loop to add to it

或者

2)将行中的ia更改为36

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

不要两个都做!选一个。

于 2013-11-12T20:49:15.723 回答
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;
}
于 2013-11-12T21:48:25.947 回答