152 lines
4.4 KiB
C#
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 // 毫米波终端制导
|
|
}
|
|
|
|
}
|