[英]Project an object with rotation around another object in C++/OpenGL
我正在使用OpenGL / C ++創建游戲。
我正在研究的這款游戲的一個方面是,有一個角色會按照所述角色面對的方式射擊彈丸。 為此,我有一個“玩家”和一個“彈丸”。
我將角色x和y坐標(玩家所面對的角度)傳遞給射彈。 因此,我想朝那個方向射擊。
在我的畫圖中,我目前正在使用帶有字符x和y的glTranslate,並以字符面對的方式旋轉彈丸。 這會將我的彈丸移動到玩家面對的方式。
glTranslatef(this->m_X, this->m_Y, 0);
glRotatef(angle, 0, 0, 1);
這就是我遇到的問題,我可以通過增加/減少平移中的X和Y值來移動彈丸位置。 但是我想問的是如何使彈丸沿着玩家所面對的線移動。
謝謝您的幫助!
您可以將極向量用於這些計算。
http://mathworld.wolfram.com/PolarVector.html
極坐標向量將使您能夠進行通常很復雜且以簡單方式難以計算的幾種計算。 使用他們的應用數學,您的請求將不會成為問題。
這是我的極向量的實現。
頭文件:
#include <cmath>
//Using SFML Vector2 class, making a similar class is easy.
//Check this URL: http://www.sfml-dev.org/documentation/2.3.2/classsf_1_1Vector2.php
class PolarVector
{
public:
float r;
float t; ///Angle stored in degrees.
PolarVector();
PolarVector(float radius, float angle);
PolarVector(const sf::Vector2f V2); ///Conversion constructor.
sf::Vector2f TurnToRectangular() const;
};
PolarVector TurnToPolar(const sf::Vector2f point);
float getConvertedRadius(const sf::Vector2f point);
float getConvertedAngle(sf::Vector2f point);
bool operator ==(const PolarVector& left, const PolarVector& right);
bool operator !=(const PolarVector& left, const PolarVector& right);
和源文件:
#include "PolarVector.hpp"
PolarVector::PolarVector()
:r(0.f)
,t(0.f)
{}
PolarVector::PolarVector(float radius, float angle)
:r(radius)
,t(angle)
{}
PolarVector::PolarVector(const sf::Vector2f V2)
:r(getConvertedRadius(V2))
,t(getConvertedAngle(V2))
{}
sf::Vector2f PolarVector::TurnToRectangular() const
{ return sf::Vector2f(static_cast<float>(r* std::cos(t)), static_cast<float>(r* std::sin(t))); }
PolarVector TurnToPolar(const sf::Vector2f point)
{
PolarVector PV;
PV.r = getConvertedAngle(point);
PV.t = getConvertedRadius(point);
return PV;
}
float getConvertedRadius(const sf::Vector2f point)
{ return std::sqrt((point.x * point.x) + (point.y * point.y) ); }
float getConvertedAngle(const sf::Vector2f point)
{ return std::atan2(point.y, point.x); }
bool operator ==(const PolarVector& left, const PolarVector& right)
{
float diffR = left.r - right.r;
float diffA = left.t - right.t;
return ((diffR <= EPSILON) && (diffA <= EPSILON));
}
bool operator !=(const PolarVector& left, const PolarVector& right)
{
float diffR = left.r - right.r;
float diffA = left.t - right.t;
return !((diffR <= EPSILON) && (diffA <= EPSILON));
}
我建議這樣做的原因是因為您可以執行以下操作。
假設您有一個二維向量:
sf::Vector2f character(0.f, 0.f); //Origin point. First parameter is X, second is Y
float angleCharFacesAt = 0.698132; //40 degrees in radians. C++ Trigonometry uses Radians. std::cos, std::sin and std::atan2 are used internally.
對於第一個對象或角色。 您希望另一個對象具有相同的角度,但位置不同。
假設另一個對象在其上方有一個位置:
sf::Vector2f object(0.f, 10.f); //Above the origin point.
float angleObjectFacesAt = 0.f; //0 degrees.
因此,您需要做的就是使用極向量旋轉它:
PolarVector PV = TurnToPolar(object); //Use this for calculations.
PV.t += angleCharFacesAt; //t is the angle parameter of the polar vector.
object = PV.TurnToRectangular(object);
這樣,您將獲得對象的旋轉位置。
一個物體和另一個物體之間的距離將始終是極向量的r(半徑)值。 因此,您可以通過以下方法使距離更長或更短:
PolarVector PV = TurnToPolar(object); //Use this for calculations.
PV.r += 10; //Increase the radius to increase the distance between the objects.
object = PV.TurnToRectangular(object);
您應該嘗試了解旋轉矩陣和極坐標數學,以便以此實現更多的事情,但是使用此代碼是可能的。 您還應該將所有這些代碼放在一個類中,但是請首先使用它,直到您對它有所了解。
很抱歉提供冗長的答案,但這是一個無需深入研究線性代數就很難解釋的話題。 這些類用於實際的代碼可管理性(我在自己的游戲中使用它們),但是您只能通過計算來重現相同的效果。
我個人更喜歡Polar Vectors,而不是使用旋轉矩陣,這是因為Polar Vectors不僅可以旋轉對象,而且還很有用。 但是這里有一個鏈接,可以更好地理解旋轉矩陣: https : //en.wikipedia.org/wiki/Rotation_matrix
使用極坐標向量完成轉換后,您可以將glTranslate轉換為極坐標向量給出的最終位置。 您必須確保圍繞使用的原點旋轉。 否則,旋轉可能不會如您期望的那樣發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.