struct Vector
{
public double X { get; }
public double Y { get; }
public Vector(double x, double y)
{
X = x; Y = y;
}
public static readonly Vector Reference = new Vector(1, 0);
// Угол в градусах относительно опорного, возвращает значение из диапазона (-180°; 180°]
public static double AngleOfReference(Vector v)
=> Math.Atan2(v.Y, v.X) / Math.PI * 180;
}
// создаем первый вектор
var start1 = new Point { X = 1, Y = 1 };
var end1 = new Point { X = 2, Y = 2 };
var vector1 = Vector.FromPoints(start1, end1);
// создаем второй вектор
var start2 = new Point { X = 2, Y = 2 };
var end2 = new Point { X = 1, Y = 1 };
var vector2 = Vector.FromPoints(start2, end2);
// вычисляем угол в радианах
var angleRad = Vector.CalculateAngleBetween(vector1, vector2);
// переводим угол в градусы
var angleDegree = angleRad / Math.PI * 180;
Console.WriteLine(angleDegree);
两个类Point和Vector:
public class Point
{
public double X { get; set; }
public double Y { get; set; }
}
public class Vector
{
public double X { get; private set; }
public double Y { get; private set; }
public double Length { get; private set; }
private Vector(double x, double y)
{
X = x;
Y = y;
CalculateLength();
}
// вычисляет вектор по двум точкам
public static Vector FromPoints(Point start, Point end)
{
return new Vector(start.X - end.X, start.Y - end.Y);
}
// вычисляет угол между веторами
public static double CalculateAngleBetween(Vector vector1, Vector vector2)
{
if (vector1.Length == 0 || vector2.Length == 0)
{
throw new ArgumentOutOfRangeException(vector1.Length == 0 ? nameof(vector1) : nameof(vector2), "Vector can not be with zero lenght");
}
var scalarMultiplier = vector1 * vector2;
var cos = scalarMultiplier / (vector1.Length * vector2.Length);
var angle = Math.Acos(cos);
return angle;
}
// вычисляет скалярное произведение векторов
public static double operator *(Vector a, Vector b)
{
return a.X * b.X + a.Y * b.Y;
}
// вычисляет длину вектора
private void CalculateLength()
{
var xPow2 = X * X;
var yPow2 = Y * Y;
var sum = xPow2 + yPow2;
var sqrt = Math.Sqrt(sum);
Length = sqrt;
}
}
让我们采用一些“参考”(“起始”)向量,我们将其视为原点。我采用了向量 (1; 0) - 这会稍微简化计算。
代码将在 C# 中:
然后,有序向量对之间的角度将计算为:
Vector.AngleOfReference(a) - Vector.AngleOfReference(b);,但是,正如@VladD 在评论中正确建议的那样,输出可以是 (-360; 360] 范围内的值,它需要“归一化”,所以我仍然会在结构中添加一个方法来计算角度:这将为我们提供一个恰好在 (-180°; 180°] 范围内的角度。
另一个小改进,我将给出结果结构的完整代码:
通过调整
NormalizeAngle您可以选择所需的输出范围。在上面的代码[0°; 360°)中,如果您需要它(-180°; 180°],请像这样更正它:基本的一切都很简单!
计算向量之间的值:
两个类
Point和Vector:在线计算器在这里。
测试!