在 C# 中找到直线与 X 轴的最小角度
find the least angle of a line to X axis in C#
假设我们通过减去两条线的端点来定义两个向量。
V1 = Pa - Pb;
V2 = Pc - Pd;
我们将X轴定义为如下向量。
var V = new System.Windows.Vector(1, 0);
我们如何知道两个向量V1和V2中哪一个与X轴的角度最小
对两者进行归一化并找到 x 绝对值较高的一个。
或者,两个向量 a
和 b
之间的角度是 arccos((a.x*b.x+a.y*b.y)/(a.Length*b.Length))
(如果其中一个向量为零,则未定义)
您有两个选择:您可以使用 AngleBetween
函数计算 V1
和 V
以及 V2
和 V
之间的角度:
var angle1 = Vector.AngleBetween(V1,V);
var angle2 = Vector.AngleBetween(V2,V);
if (angle1 < angle2) {
//V1 is closer to V
}else{
//V2 is closer to V
}
或者你也可以规范化你的向量,然后比较它们的 y
值:
V1.Normalize();
V2.Normalize();
if(Math.Abs(V1.Y) < Math.Abs(V2.Y)){
//V1 is closer
}else{
//V2 is closer
}
我更喜欢第一种方法,因为 Normalize()
函数实际上更改了原始 Vector,因此如果您以后想使用它们,则需要制作一个副本。您也可以使用第一个版本将它们与任何其他向量进行比较 V
,而无需调整代码。
编辑:实际上第一个版本只选择与V
向量成最小角度的向量,而不是而不是到x轴的向量。因此,如果你想与轴进行比较而不仅仅是向量,你应该使用 V1
和 V2
的副本与绝对 x
和 y
值进行角度计算:
var ref1 = new System.Windows.Vector(Math.Abs(V1.X),Math.Abs(V1.Y));
var ref2 = new System.Windows.Vector(Math.Abs(V2.X),Math.Abs(V2.Y));
var angle1 = Vector.AngleBetween(ref1,V);
var angle2 = Vector.AngleBetween(ref2,V);
if (angle1 < angle2) {
//V1 is closer to V
}else{
//V2 is closer to V
}
这样看,归一化方法可能毕竟是更好的选择。 (但一定要在副本上调用Normalize()
)
double compare() {
Point p0 = new Point(0, 0);
Point p1 = new Point(100, 100);
Point p2 = new Point(100, -100);
Vector v0 = new System.Windows.Vector(1, 0);
var v1 = p1 - p0;
var v2 = p2 - p0;
var value1 = Vector.AngleBetween(v0, v1); //value = 45
var value2 = Vector.AngleBetween(v0, v2); //value = -45
value1 = Math.Abs(value1);
value2 = Math.Abs(value2);
/* Or if you want to compare the value of the angle
if (value1 < 0)
value1 += 360;
if (value2 < 0)
value2 += 360;
*/
return Math.Min(value1,value2);
}
检查以下解决方案。可以完成您的 query.Add 参考 Windowsbase 项目。非常重要。
using System;
using System.Windows;
namespace Vectors
{
class Program
{
static void Main(string[] args)
{
// Define Points
Point Pa = new Point(5.0,1.0);
Point Pb = new Point(10.0,3.0);
Point Pc = new Point(7.0,10.0);
Point Pd = new Point(1.0,3.0);
Vector V1 = Pa - Pb;
Vector V2 = Pc - Pd;
Vector V = new Vector(1, 0);
double Phi1 = Math.Atan2(V1.Y, V1.X)*180/Math.PI;
double Phi2 = Math.Atan2(V2.Y, V2.X)*180/Math.PI;
// Check for -ve angle and take 180 degree complement.
Phi1 = (Phi1 >= 0) ? Phi1 : 180 + Phi1;
Phi2 = (Phi2 >= 0) ? Phi2 : 180 + Phi2;
if(Phi1<=Phi2)
{
Console.WriteLine("Vector V1 has a least angle");
}
else
{
Console.WriteLine("Vector V2 has a least angle");
}
Console.ReadLine();
}
}
}
假设我们通过减去两条线的端点来定义两个向量。
V1 = Pa - Pb;
V2 = Pc - Pd;
我们将X轴定义为如下向量。
var V = new System.Windows.Vector(1, 0);
我们如何知道两个向量V1和V2中哪一个与X轴的角度最小
对两者进行归一化并找到 x 绝对值较高的一个。
或者,两个向量 a
和 b
之间的角度是 arccos((a.x*b.x+a.y*b.y)/(a.Length*b.Length))
(如果其中一个向量为零,则未定义)
您有两个选择:您可以使用 AngleBetween
函数计算 V1
和 V
以及 V2
和 V
之间的角度:
var angle1 = Vector.AngleBetween(V1,V);
var angle2 = Vector.AngleBetween(V2,V);
if (angle1 < angle2) {
//V1 is closer to V
}else{
//V2 is closer to V
}
或者你也可以规范化你的向量,然后比较它们的 y
值:
V1.Normalize();
V2.Normalize();
if(Math.Abs(V1.Y) < Math.Abs(V2.Y)){
//V1 is closer
}else{
//V2 is closer
}
我更喜欢第一种方法,因为 Normalize()
函数实际上更改了原始 Vector,因此如果您以后想使用它们,则需要制作一个副本。您也可以使用第一个版本将它们与任何其他向量进行比较 V
,而无需调整代码。
编辑:实际上第一个版本只选择与V
向量成最小角度的向量,而不是而不是到x轴的向量。因此,如果你想与轴进行比较而不仅仅是向量,你应该使用 V1
和 V2
的副本与绝对 x
和 y
值进行角度计算:
var ref1 = new System.Windows.Vector(Math.Abs(V1.X),Math.Abs(V1.Y));
var ref2 = new System.Windows.Vector(Math.Abs(V2.X),Math.Abs(V2.Y));
var angle1 = Vector.AngleBetween(ref1,V);
var angle2 = Vector.AngleBetween(ref2,V);
if (angle1 < angle2) {
//V1 is closer to V
}else{
//V2 is closer to V
}
这样看,归一化方法可能毕竟是更好的选择。 (但一定要在副本上调用Normalize()
)
double compare() {
Point p0 = new Point(0, 0);
Point p1 = new Point(100, 100);
Point p2 = new Point(100, -100);
Vector v0 = new System.Windows.Vector(1, 0);
var v1 = p1 - p0;
var v2 = p2 - p0;
var value1 = Vector.AngleBetween(v0, v1); //value = 45
var value2 = Vector.AngleBetween(v0, v2); //value = -45
value1 = Math.Abs(value1);
value2 = Math.Abs(value2);
/* Or if you want to compare the value of the angle
if (value1 < 0)
value1 += 360;
if (value2 < 0)
value2 += 360;
*/
return Math.Min(value1,value2);
}
检查以下解决方案。可以完成您的 query.Add 参考 Windowsbase 项目。非常重要。
using System;
using System.Windows;
namespace Vectors
{
class Program
{
static void Main(string[] args)
{
// Define Points
Point Pa = new Point(5.0,1.0);
Point Pb = new Point(10.0,3.0);
Point Pc = new Point(7.0,10.0);
Point Pd = new Point(1.0,3.0);
Vector V1 = Pa - Pb;
Vector V2 = Pc - Pd;
Vector V = new Vector(1, 0);
double Phi1 = Math.Atan2(V1.Y, V1.X)*180/Math.PI;
double Phi2 = Math.Atan2(V2.Y, V2.X)*180/Math.PI;
// Check for -ve angle and take 180 degree complement.
Phi1 = (Phi1 >= 0) ? Phi1 : 180 + Phi1;
Phi2 = (Phi2 >= 0) ? Phi2 : 180 + Phi2;
if(Phi1<=Phi2)
{
Console.WriteLine("Vector V1 has a least angle");
}
else
{
Console.WriteLine("Vector V2 has a least angle");
}
Console.ReadLine();
}
}
}