/
EugenyCh7
/
Puppet2D.Net
Обзор
Документация
Войти
/
EugenyCh7
/
Puppet2D.Net
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Puppet2D.Engine/Common/Rotation.cs
197 строк
6 KB
EugenyCh7
++ Rotation
25 авг 2025, 22:00
25 авг 2025, 22:00
1d25da5
Код
Авторство
О чём код?
using Puppet2D.System; using System; namespace Puppet2D.Engine.Common { /// <summary> /// Represents a 2D rotation using cosine and sine values for efficient computation. /// This structure avoids expensive trigonometric calculations by storing precomputed cos/sin values. /// </summary> public struct Rotation { /// <summary> /// The cosine component of the rotation angle. /// </summary> public float Cos; /// <summary> /// The sine component of the rotation angle. /// </summary> public float Sin; /// <summary> /// Initializes a new instance of the Rotation struct with specified cosine and sine values. /// </summary> /// <param name="cos">The cosine of the rotation angle</param> /// <param name="sin">The sine of the rotation angle</param> public Rotation(float cos, float sin) { Cos = cos; Sin = sin; } /// <summary> /// Initializes a new instance of the Rotation struct from an angle in radians. /// Automatically computes the cosine and sine values. /// </summary> /// <param name="angle">The rotation angle in radians</param> public Rotation(float angle) { Cos = MathF.Cos(angle); Sin = MathF.Sin(angle); } /// <summary> /// Gets or sets the rotation angle in radians. /// When getting, returns the angle in the range [-π, π]. /// When setting, automatically updates the cosine and sine values. /// </summary> public float Angle { get => MathF.Atan2(Sin, Cos); set { Cos = MathF.Cos(value); Sin = MathF.Sin(value); } } /// <summary> /// Gets the identity rotation (no rotation). /// Equivalent to a rotation angle of 0 radians. /// </summary> public static Rotation Identity { get => new Rotation(1f, 0f); } /// <summary> /// Gets the x-axis unit vector of the rotation matrix. /// Represents the direction of the rotated x-axis (cos, sin). /// </summary> public Vector2 XAxis { get => new Vector2(Cos, Sin); } /// <summary> /// Gets the y-axis unit vector of the rotation matrix. /// Represents the direction of the rotated y-axis (-sin, cos). /// </summary> public Vector2 YAxis { get => new Vector2(-Sin, Cos); } /// <summary> /// Rotates a vector by this rotation. /// Applies the rotation matrix to the given vector. /// </summary> /// <param name="v">The vector to rotate</param> /// <returns>The rotated vector</returns> public Vector2 RotateVector(Vector2 v) { return new Vector2( Cos * v.X - Sin * v.Y, Sin * v.X + Cos * v.Y ); } /// <summary> /// Inverse rotates a vector by this rotation. /// Applies the inverse rotation matrix to the given vector. /// </summary> /// <param name="v">The vector to inverse rotate</param> /// <returns>The inverse rotated vector</returns> public Vector2 InvRotateVector(Vector2 v) { return new Vector2( Cos * v.X + Sin * v.Y, -Sin * v.X + Cos * v.Y ); } /// <summary> /// Multiplies two rotations: this * other. /// Combines two rotations by applying this rotation followed by the other rotation. /// </summary> /// <param name="other">The rotation to multiply with</param> /// <returns>The combined rotation representing this rotation followed by the other rotation</returns> public Rotation Mul(Rotation other) { return new Rotation( Cos * other.Cos - Sin * other.Sin, Sin * other.Cos + Cos * other.Sin ); } /// <summary> /// Transpose multiply two rotations: this^T * other. /// Computes the relative rotation from this rotation to the other rotation. /// </summary> /// <param name="other">The rotation to multiply with</param> /// <returns>The relative rotation from this rotation to the other rotation</returns> public Rotation InvMul(Rotation other) { return new Rotation( Cos * other.Cos + Sin * other.Sin, Cos * other.Sin - Sin * other.Cos ); } /// <summary> /// Normalizes the rotation to ensure cos² + sin² = 1 /// </summary> /// <returns>Normalized rotation</returns> public Rotation Normalized() { float mag = MathF.Sqrt(Sin * Sin + Cos * Cos); if (mag > 0.0f) { float invMag = 1.0f / mag; return new Rotation(Cos * invMag, Sin * invMag); } else { return new Rotation(1.0f, 0.0f); // Return identity rotation if magnitude is zero } } /// <summary> /// Checks if this rotation is normalized (cos² + sin² ≈ 1) /// </summary> /// <returns>True if rotation is normalized, false otherwise</returns> public bool IsNormalized { get { float qq = Sin * Sin + Cos * Cos; return 1.0f - 0.0006f < qq && qq < 1.0f + 0.0006f; } } /// <summary> /// Normalizes this rotation in-place /// </summary> public void Normalize() { float mag = MathF.Sqrt(Sin * Sin + Cos * Cos); if (mag > 0.0f) { float invMag = 1.0f / mag; Cos *= invMag; Sin *= invMag; } else { Cos = 1.0f; Sin = 0.0f; // Set to identity rotation if magnitude is zero } } public override string ToString() { return $"[Rotation] Cos({Cos}) Sin({Sin})"; } } }