我正在写一个函数的几何有点麻烦。我有一个包含各种精灵的类。这个容器类需要能够移动,旋转和缩放,同时保持所有子精灵的相对位置,旋转和比例不变。
旋转容器时遇到问题。由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”变量,我会在圆周上得到随机点(左下角,右上角,左下角,左边的圆圈,右边的圆圈等)
感谢您阅读本文。对此,我真的非常感激。我完全陷入了困境。任何帮助都会很棒。
答案 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;
}