如果我有兩個點p1和p2,其中p1是樞軸點,p2是用戶前進的原始方向,並且它們有多個可能的方向以隨機順序前進到p3 ... pn。我如何獲得選擇和由p1,p2形成的片段之間的角度作爲順時針(右手)0至360之間的正值,以便我可以將它們從最小到最大排序?2D中的順時針旋轉角度?
此外,點p1 ... pn將在任何象限中,我不能假設它們將始終處於正x,y方向。網格是一個標準的笛卡爾網格而不是屏幕座標,因此當你下降不大時,Y會變小。
在這個例子中所以(對不起,窮人圖紙,但塗料是所有我對我的筆記本電腦),我需要的角度:
(P2-P1- P3) (P2-P1-P4) (P2-P1-P5) (P2-P1-P6)
在這個順序(最小的右手轉大右轉): [(P2-P1-P4),(P2-P1-P6),(P2-P1-P5),(P2-P1-P3)]
在我的情況的點是一個所謂的頂點類:
public class Vertex
{
public double X = 0;
public double Y = 0;
public Vertex() { }
public Vertex(double x, double y)
{
X = x;
Y = y;
}
}
併爲獲取角度,現在的排序看起來像這樣的權利,但代碼中有一個問題:
private static IEnumerable<Vertex> SortByAngle(Vertex original, Vertex pivot, List<Vertex> choices)
{
choices.Sort((v1, v2) => GetTurnAngle(original, pivot, v1).CompareTo(GetTurnAngle(original, pivot, v2)));
return choices;
}
private static double GetTurnAngle(Vertex original, Vertex pivot, Vertex choice)
{
var a = original.X - pivot.X;
var b = original.Y - pivot.Y;
var c = choice.X - pivot.X;
var d = choice.Y - pivot.Y;
var rads = Math.Acos(((a * c) + (b * d))/((Math.Sqrt(a * a + b * b)) * (Math.Sqrt(c * c + d * d))));
return (180/Math.PI * rads);
}
的問題是上面的是,如果我檢查了:原來 66,-66 支點280,-191 選擇200,-180
我得到的角度是22.460643124,而不是337.539356876,這意味着它從原來的方向逆時針旋轉得到那個角度。我需要它總是順時針旋轉來獲得角度。
我在做什麼錯,我該如何解決?
更新:行,所以根據在說什麼你們我大概可以使用一些跨產品如數學來確定CW VS CCW因此新的方法是這樣的:
private static double GetTurnAngle(Vertex original, Vertex pivot, Vertex choice)
{
var a = original.X - pivot.X;
var b = original.Y - pivot.Y;
var c = choice.X - pivot.X;
var d = choice.Y - pivot.Y;
var angle = Math.Acos(((a * c) + (b * d))/((Math.Sqrt(a * a + b * b)) * (Math.Sqrt(c * c + d * d))));
angle = (180/Math.PI * angle);
var z = (choice.X - pivot.X) * (original.Y - pivot.Y) - (choice.Y - pivot.Y) * (original.X - pivot.X);
if (z < 0)
{
return 360 - angle;
}
return angle;
}
更新2:
使用接受的解決方案,現在看起來像這樣:
private static double GetTurnAngle(Vertex original, Vertex pivot, Vertex choice)
{
var angle1 = Math.Atan2(original.Y - pivot.Y, original.X - pivot.X);
var angle2 = Math.Atan2(choice.Y - pivot.Y, choice.X - pivot.X);
var angleDiff = (180/Math.PI * (angle2 - angle1));
if (angleDiff > 0)//It went CCW so adjust
{
return 360 - angleDiff;
}
return -angleDiff;//I need the results to be always positive so flip sign
}
到目前爲止,我可以告訴大家,偉大的工程至今。謝謝你們的幫助!
p2是點還是方向(例如矢量)?第一句話沒有定論。 – kkuilla
實際的差異角度是22度,而不是337.您將需要使用360 - 如果您希望從360開始而不是0開始,則需要使用360結果。 – KSdev
看起來您只能在某處加上/減號 - 您有嗎?嘗試通過排列「a」到「d」的排列來循環嘗試?我意識到理想的解決方案是要知道爲什麼數學是錯誤的,但如果它的工作... – norlesh