我怎样才能让角度不表现得很奇怪?

How can I make angles not act weird?

我是编程和 SFML 的新手。我正在尝试制作类似经典的东西。它会发射呈弧形飞行的球。听起来这是一项非常简单的任务,但我似乎无法弄清楚角度在 SFML 中是如何工作的。例如,在 ang_const = 0.13 Rad (7.44 Deg) 的情况下,我的球以美丽的弧线飞行。但是,当我将 ang_const 的值更改为 0.14 Rad (8.021 Deg) 时,球会朝相反的方向飞行!如果我将角度更改为 0.19 Rad (10.88 Deg),它会出于某种原因向下飞行。

所以这是我的代码:

#include <SFML/Graphics.hpp>
#include <math.h>
int WIDTH = 1024, HEIGHT = 704;

class Ball {
private:
float radius = 16.00;
public:
sf::CircleShape shape;
Ball () {
    shape.setPosition(0 + radius*2, HEIGHT - radius*2);
    shape.setRadius(radius);
    shape.setFillColor(sf::Color::Cyan);
    shape.setOrigin(radius, radius);
}
void update() {
    if (x() - radius > WIDTH) {
        this->shape.setPosition(0 - radius, y());
    }
    if (x() + radius < 0) {
        this->shape.setPosition(WIDTH + radius, y());
    }
    if (y() - radius > HEIGHT) {
        this->shape.setPosition(x(), 0 - radius);
    }
    if (y() + radius < 0) {
        this->shape.setPosition(x(), HEIGHT + radius);
    }
}
float RadToDeg (float radian) {
    double pi = 3.14159;
    return radian * (180 / pi);
}
float x() { return shape.getPosition().x; }
float y() { return shape.getPosition().y; }
float getRadius() { return radius; }
};

int main()
{
// Create the main window
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "del");

// Some variables
float ang_const = 0.13;                   
float velX_const = 3.5, velY_const = 3.5; 
float grav_const = -0.02;                

float ang = ang_const;
float velX = velX_const, velY = velY_const;
float grav = grav_const;

// Text
int size_for_text = 64;
sf::Font f;
f.loadFromFile("Keyboard.ttf");
sf::Text text1;
text1.setFont(f);
text1.setCharacterSize(27);
text1.setFillColor(sf::Color::White);
text1.setPosition(size_for_text, size_for_text);

// Ball
Ball ball;

while (window.isOpen())
{
    // Process events
    sf::Event event;
    while (window.pollEvent(event))
    {
        // Close window: exit
        if (event.type == sf::Event::Closed) {
            window.close();
        }

        // Escape pressed: exit
        if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
            window.close();
        }

        // Restart
        if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space) {
            ang = ang_const;
            velX = velX_const, velY = velY_const;
            grav = grav_const;
            ball.shape.setPosition(0 + ball.getRadius()*2, HEIGHT - ball.getRadius()*2);
        }
    }

    // Ball movement
    ball.update();

    velY += grav;
    ball.shape.move(velX * cos(ball.RadToDeg(ang)),
                    velY * -sin(ball.RadToDeg(ang)));

    // Clear screen
    window.clear(sf::Color(0,0,80,100));

    // Draw ball
    window.draw(ball.shape);

    // Draw text
    text1.setString("ang " + std::to_string(ang));
    window.draw(text1);

    // Update the window
    window.display();
}

return EXIT_SUCCESS;
}

主要内容如下: 变量:

float ang_const = 0.13;                 
float velX_const = 3.5, velY_const = 3.5;
float grav_const = -0.02;               

球运动:

velY += grav;
ball.shape.move(velX * cos(ball.RadToDeg(ang)), velY * - 
sin(ball.RadToDeg(ang)));

弧度转度函数:

float RadToDeg (float radian) {
double pi = 3.14159;
return radian * (180 / pi);
}

有人可以解释一下我的代码有什么问题以及角度在 SFML 中是如何工作的吗?我将不胜感激你们的帮助。

<cmath> 中定义的所有三角函数都期望它们的参数是表示 弧度 角度的值(参见 std::cos)。

所以,当你写类似

的东西时
cos(ball.RadToDeg(ang))

其中 ang 等于 0.13,RadToDeg 会将其转换为 7.44,但是,即使您打算以度为单位传递角度,该值也会被解释为 std::cos(和 std::sin)的角度为 7.44 弧度(或 66.28°)。

这会导致您意想不到的结果:

cosr(7.44) = 0.505(而不是 cosd(7.44° ) = 0.993) 和
cosr(8.021) = -0.166(而不是 cosd(8.021°) = 0.992)