ActiveProtect/Models/Common.cs

152 lines
4.4 KiB
C#

using System;
namespace ActiveProtect.Models
{
public class Vector3D(double x, double y, double z)
{
public double X { get; set; } = x;
public double Y { get; set; } = y;
public double Z { get; set; } = z;
public static double Distance(Vector3D v1, Vector3D v2)
{
return Math.Sqrt(Math.Pow(v1.X - v2.X, 2) + Math.Pow(v1.Y - v2.Y, 2) + Math.Pow(v1.Z - v2.Z, 2));
}
public static Vector3D Zero => new(0, 0, 0);
public override string ToString()
{
return $"({X:F2}, {Y:F2}, {Z:F2})";
}
public static Vector3D operator -(Vector3D a, Vector3D b)
{
return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}
public static Vector3D operator +(Vector3D a, Vector3D b)
{
return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
}
public static Vector3D operator *(Vector3D a, double scalar)
{
return new Vector3D(a.X * scalar, a.Y * scalar, a.Z * scalar);
}
public static Vector3D operator /(Vector3D a, double scalar)
{
return new Vector3D(a.X / scalar, a.Y / scalar, a.Z / scalar);
}
public double Magnitude()
{
return Math.Sqrt(X * X + Y * Y + Z * Z);
}
public double MagnitudeSquared()
{
return X * X + Y * Y + Z * Z;
}
public Vector3D Normalize()
{
double mag = Magnitude();
if (mag > 0)
{
return new Vector3D(X / mag, Y / mag, Z / mag);
}
return new Vector3D(0, 0, 0);
}
public static Vector3D CrossProduct(Vector3D a, Vector3D b)
{
return new Vector3D(
a.Y * b.Z - a.Z * b.Y,
a.Z * b.X - a.X * b.Z,
a.X * b.Y - a.Y * b.X
);
}
public static double DotProduct(Vector3D a, Vector3D b)
{
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
}
}
public struct Orientation(double yaw, double pitch, double roll)
{
public double Yaw { get; set; } = yaw;
public double Pitch { get; set; } = pitch;
public double Roll { get; set; } = roll;
public override readonly string ToString()
{
return $"(Yaw: {Yaw:F2}, Pitch: {Pitch:F2}, Roll: {Roll:F2})";
}
public void Normalize()
{
Yaw = NormalizeAngle(Yaw);
Pitch = NormalizeAngle(Pitch);
Roll = NormalizeAngle(Roll);
}
private static double NormalizeAngle(double angle)
{
while (angle > Math.PI) angle -= 2 * Math.PI;
while (angle <= -Math.PI) angle += 2 * Math.PI;
return angle;
}
public static Orientation LookAt(Vector3D direction)
{
double yaw = Math.Atan2(direction.Z, direction.X);
double pitch = Math.Atan2(direction.Y, Math.Sqrt(direction.X * direction.X + direction.Z * direction.Z));
return new Orientation(yaw, pitch, 0);
}
public readonly Vector3D ToVector()
{
double cosYaw = Math.Cos(Yaw);
double sinYaw = Math.Sin(Yaw);
double cosPitch = Math.Cos(Pitch);
double sinPitch = Math.Sin(Pitch);
return new Vector3D(
cosYaw * cosPitch,
sinPitch,
sinYaw * cosPitch
);
}
public static Orientation FromVector(Vector3D vector)
{
Vector3D normalized = vector.Normalize();
double pitch = Math.Asin(normalized.Y);
double yaw;
if (Math.Abs(normalized.Y) > 0.9999) // 接近垂直
{
yaw = 0; // 或者保持之前的偏航角
}
else
{
yaw = Math.Atan2(normalized.Z, normalized.X);
}
return new Orientation(yaw, pitch, 0);
}
}
public enum MissileType
{
StandardMissile, // 标准导弹
SemiActiveLaserGuidance, // 半主动激光制导
LaserBeamRiderGuidance, // 激光束制导
InfraredCommandGuidance, // 红外指令制导
ImagingInfraredTerminalGuidance, // 成像红外终端制导
MillimeterWaveTerminalGuidance // 毫米波终端制导
}
}