3D数学基础——Rotator类的C++实现

3D数学基础——Rotator类的C++实现Rotator 类的 C 实现 FRotator 类用来以欧拉角形式保存方位 使用 pitch yaw roll 进行约定 类的定义如下 pragma once include FVector h include math h struct FRotator public math h

大家好,我是讯享网,很高兴认识大家。

Rotator类的C++实现

FRotator类用来以欧拉角形式保存方位,使用pitch-yaw-roll进行约定,类的定义如下:

#pragma once #include "FVector.h" #include <math.h> struct FRotator { public: //直接的表示方式,用角度表示 float Pitch; float Yaw; float Roll; public: //构造函数 inline FRotator() { }; explicit inline FRotator(float InF); inline FRotator(float InPitch, float InYaw, float InRoll); public: //操作符重载 / * Get the result of adding a rotator to this. * * @param R The other rotator. * @return The result of adding a rotator to this. */ FRotator operator+(const FRotator &R) const; / * Get the result of subtracting a rotator from this. * * @param R The other rotator. * @return The result of subtracting a rotator from this. */ FRotator operator-(const FRotator &R) const; / * Get the result of scaling this rotator. * * @param Scale The scaling factor. * @return The result of scaling. */ FRotator operator*(float Scale) const; / * Multiply this rotator by a scaling factor. * * @param Scale The scaling factor. * @return Copy of the rotator after scaling. */ FRotator operator*=(float Scale); // Unary operators. / * Get a negated copy of the rotator. * * @return A negated copy of the rotator. */ inline FRotator operator-() const; // Binary comparison operators. / * Checks whether two rotators are identical. * * @param R The other rotator. * @return true if two rotators are identical, otherwise false. */ bool operator==(const FRotator &R) const; / * Checks whether two rotators are different. * * @param V The other rotator. * @return true if two rotators are different, otherwise false. */ bool operator!=(const FRotator &V) const; // Assignment operators. / * Adds another rotator to this. * * @param R The other rotator. * @return Copy of rotator after addition. */ FRotator operator+=(const FRotator &R); / * Subtracts another rotator from this. * * @param R The other rotator. * @return Copy of rotator after subtraction. */ FRotator operator-=(const FRotator &R); public: // Functions. / * Checks whether this has exactly zero rotation. * * @return true if this has exactly zero rotation, otherwise false. */ bool IsZero() const; / * Adds to each component of the rotator. * * @param DeltaPitch Change in pitch. (+/-) * @param DeltaYaw Change in yaw. (+/-) * @param DeltaRoll Change in roll. (+/-) * @return Copy of rotator after addition. */ FRotator Add(float DeltaPitch, float DeltaYaw, float DeltaRoll); / * Convert a rotation into a vector facing in its direction. * * @return Rotation as a direction vector. */ FVector Vector() const; / * Convert a Rotator into floating-point Euler angles (in degrees). Rotator now stored in degrees. * * @return Rotation as a Euler angle vector. */ FVector Euler() const; / * Rotate a vector rotated by this rotator. * * @param V The vector to rotate. * @return The rotated vector. */ FVector RotateVector(const FVector& V) const; / * Returns the vector rotated by the inverse of this rotator. * * @param V The vector to rotate. * @return The rotated vector. */ FVector UnrotateVector(const FVector& V) const; / * Gets the rotation values so they fall within the range [0,360] * * @return Clamped version of rotator. */ FRotator Clamp() const; public: //TODO //explicit FRotator(const FQuat& Quat); / * Get Rotation as a quaternion. * * @return Rotation as a quaternion. */ //FQuat Quaternion() const; public: / * Clamps an angle to the range of [0, 360]. * * @param Angle The angle to clamp. * @return The clamped angle. */ static float ClampAxis(float Angle); / * Clamps an angle to the range of [-180, 180]. * * @param Angle The Angle to clamp. * @return The clamped angle. */ static float NormalizeAxis(float Angle); }; / * *静态成员变量 * / inline float FRotator::ClampAxis(float Angle) { // returns Angle in the range (-360,360) Angle = fmod(Angle, 360.f); if (Angle < 0.f) { // shift to [0,360) range Angle += 360.f; } return Angle; } inline float FRotator::NormalizeAxis(float Angle) { // returns Angle in the range [0,360) Angle = ClampAxis(Angle); if (Angle > 180.f) { // shift to (-180,180] Angle -= 360.f; } return Angle; } / * *非成员变量 * / inline FRotator operator*(float Scale, const FRotator &R) { return R.operator*(Scale); } /* * *全局变量 * / //提供一个全局向量 extern const FRotator ZeroRotator; / * *类的实现 * / inline FRotator::FRotator(float InF) :Pitch(InF) ,Yaw(InF) ,Roll(InF) { } inline FRotator::FRotator(float InPitch, float InYaw, float InRoll) :Pitch(InPitch) ,Yaw(InYaw) ,Roll(InRoll) { } inline FRotator FRotator::operator+(const FRotator &R) const { return FRotator(Pitch + R.Pitch, Yaw + R.Yaw, Roll + R.Roll); } inline FRotator FRotator::operator-(const FRotator &R) const { return FRotator(Pitch - R.Pitch, Yaw - R.Yaw, Roll - R.Roll); } inline FRotator FRotator::operator*(float Scale) const { return FRotator(Pitch*Scale, Yaw*Scale, Roll*Scale); } inline FRotator FRotator::operator*= (float Scale) { Pitch = Pitch*Scale; Yaw = Yaw*Scale; Roll = Roll*Scale; return *this; } inline FRotator FRotator::operator-() const { return FRotator(-Pitch, -Yaw, -Roll); } inline bool FRotator::operator==(const FRotator &R) const { return Pitch == R.Pitch && Yaw == R.Yaw && Roll == R.Roll; } inline bool FRotator::operator!=(const FRotator &V) const { return Pitch != V.Pitch || Yaw != V.Yaw || Roll != V.Roll; } inline FRotator FRotator::operator+=(const FRotator &R) { Pitch += R.Pitch; Yaw += R.Yaw; Roll += R.Roll; return *this; } inline FRotator FRotator::operator-=(const FRotator &R) { Pitch -= R.Pitch; Yaw -= R.Yaw; Roll -= R.Roll; return *this; } bool FRotator::IsZero() const { return (ClampAxis(Pitch) == 0.f) && (ClampAxis(Yaw) == 0.f) && (ClampAxis(Roll) == 0.f); } FRotator FRotator::Add(float DeltaPitch, float DeltaYaw, float DeltaRoll) { Yaw += DeltaYaw; Pitch += DeltaPitch; Roll += DeltaRoll; return *this; } FRotator FRotator::Clamp() const { return FRotator(ClampAxis(Pitch), ClampAxis(Yaw), ClampAxis(Roll)); } 

讯享网

创建MathUtil.h 和 MathUtil.cpp 用来管理 数学常数 和 常用的工具函数,以及FRotator 和 其他类中复杂函数的实现都将在MathUtil.cpp中实现;Math.h的实现如下:

讯享网#pragma once #include <math.h> const float kPi = 3.f; const float k2Pi = kPi * 2.f; const float kPiOver2 = kPi / 2.f; const float k1OverPi = 1.f / kPi; const float k1Over2Pi = 1.f / k2Pi; //安全的反三角函数 extern float safeAcos(float x); /* * 计算sin 和 cos 的值 * 在某些平台上,同时计算这两个值,要比分开计算的快 * 这里为了简单,使用标准的三角函数,注意在某些平台上可以做的更好 */ inline void sinCos(float *returnSin,float *returnCos, float theta) { *returnSin = sin(theta); *returnCos = cos(theta); } / * Converts radians to degrees. * @param RadVal Value in radians. * @return Value in degrees. */ template<class T> inline float RadiansToDegrees(T const& RadVal) { return RadVal * (180.f / kPi); } / * Converts degrees to radians. * @param DegVal Value in degrees. * @return Value in radians. */ template<class T> inline float DegreesToRadians(T const& DegVal) { return DegVal * (kPi / 180.f); } 

其中 inline void sinCos(float *returnSin,float *returnCos, float theta)  的实现有更好的实现方式,如下虚幻4的实现方式如下:

/ * Computes the sine and cosine of a scalar float. * * @param ScalarSin Pointer to where the Sin result should be stored * @param ScalarCos Pointer to where the Cos result should be stored * @param Value input angles */ static FORCEINLINE void SinCos( float* ScalarSin, float* ScalarCos, float Value ) { // Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder. float quotient = (INV_PI*0.5f)*Value; if (Value >= 0.0f) { quotient = (float)((int)(quotient + 0.5f)); } else { quotient = (float)((int)(quotient - 0.5f)); } float y = Value - (2.0f*PI)*quotient; // Map y to [-pi/2,pi/2] with sin(y) = sin(Value). float sign; if (y > HALF_PI) { y = PI - y; sign = -1.0f; } else if (y < -HALF_PI) { y = -PI - y; sign = -1.0f; } else { sign = +1.0f; } float y2 = y * y; // 11-degree minimax approximation *ScalarSin = ( ( ( ( (-2.e-08f * y2 + 2.e-06f) * y2 - 0.000f ) * y2 + 0.00f ) * y2 - 0.f ) * y2 + 1.0f ) * y; // 10-degree minimax approximation float p = ( ( ( ( -2.e-07f * y2 + 2.e-05f ) * y2 - 0.00f ) * y2 + 0.0f ) * y2 - 0.5f ) * y2 + 1.0f; *ScalarCos = sign*p; }

MathUtil.cpp 的实现如下:

讯享网#include <math.h> #include "FVector.h" #include "MathUtil.h" #include "FRotator.h" const FVector kZeroVector(0.f,0.f,0.f); /* *一些复杂的函数定义在此文件中实现 */ float safeAcos(float x) { if (x <= -1.f) { return kPi; } if (x >= 1.f) { return 0.f; } return acos(x); } / * * FRotator * / FVector FRotator::Vector() const { float CP, SP, CY, SY; sinCos(&SP, &CP, DegreesToRadians(Pitch)); sinCos(&SY, &CY, DegreesToRadians(Yaw)); FVector V = FVector(CP*CY, CP*SY, SP); return V; } FVector FRotator::Euler() const { return FVector(Roll, Pitch, Yaw); } FVector FRotator::UnrotateVector(const FVector& V) const { //TODO } FVector FRotator::RotateVector(const FVector& V) const { //TODO } 

由于其中会用到矩阵以及四元数相关,后续将实现矩阵和四元数的类,将更新这些功能函数。

 


讯享网

 

 

 

以上参考:

  • 3D数学基础:图形与游戏开发
  • unreal4 源码

 

小讯
上一篇 2025-03-15 21:24
下一篇 2025-03-24 15:56

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/119012.html