2013-07-08 40 views
5

Mogło zostać udzielone wcześniej, przepraszam, jeśli tak. Po prostu potrzebuję uzyskać kąt od początku do punktu. Powiedzmy, że Pochodzenie to (0, 0), a moim punktem docelowym jest (3, 0).Uzyskiwanie kąta między punktem a punktem wyjściowym

godzinie 3 = 90 stopni

godzinie 6 = 180 °

godzinie 9 = 270 °

godzina dwunasta = 0 stopni


W jakiś sposób muszę zrobić magię matematyczną i dowiedzieć się, że kąt wynosi 90 stopni (góra to 0). Pochodzenie może się różnić, więc potrzebuję metody z dwoma parametrami: Origin i TargetPoint, który zwraca podwójny kąt w stopniach.

Tak, zdaję sobie sprawę, wygląda to krótkie i nonconstructive, ale zrobiłem pytanie tak proste i zrozumiałe, jak to możliwe. Wszystkie pozostałe pytania zostały zamknięte -.-

Dzięki

+3

Kąt jest między dwiema liniami ... nie dwoma punktami, chyba że mówisz o kącie linii w porównaniu do, powiedzmy, samego świata? Również ... czy to jest praca domowa? – LightStriker

+0

Nie, potrzebuję kąta między punktem początkowym a punktem. Pomyśl o tym jak o zegarze, godzina 3 to 90 stopni w stosunku do początku (środek). Nie, pracuję nad grą. – Dave

+1

@LightStriker Dlaczego ludzie mają tak wiele problemów ze zrozumieniem tego pytania? ** KURSU ** nie można _technicznie_ mieć kąta między dwoma punktami, ale dlaczego tak trudno zrozumieć, że wielu programistów tego nie uczyło? Wszyscy wiedzą, że są 0 stopni i muszą znaleźć kąt, który sprawi, że jedna ikonka wskaże inny sprite. Większość programistów, którzy zadają to pytanie, po prostu nie ma tła matematycznego, aby zrozumieć koncepcję potrzeby trzech punktów (lub dwóch linii, jeśli chcesz) pod kątem. [/ rant] – Clonkex

Odpowiedz

11

Wektor między dwoma punktami A i B wynosi A = B (B.x-A.x, B.y-A.y). Kąt między dwoma wektorami można obliczyć za pomocą dot product lub atan2.

var vector2 = Target - Origin; 
var vector1 = new Point(0, 1) // 12 o'clock == 0°, assuming that y goes from bottom to top 

double angleInRadians = Math.Atan2(vector2.Y, vector2.X) - Math.Atan2(vector1.Y, vector1.X); 

Zobacz także Finding Signed Angle Between Vectors

+1

A więc: 'Math.Atan2 (Origin.Y - Target.Y, Origin.X - Target.X);'? A to jest Radians, prawda? – Dave

+0

@ user2544245: Potrzebujesz ** dwóch ** wektorów. Drugi wektor wskazuje kierunek, w którym chcesz reprezentować 0 °. Zgodnie z ruchem wskazówek zegara, tak. Twoja formuła jest jednak zła. –

+0

W twojej formule, czy ma znaczenie, który z nich jest Origin, a który jest docelowy? – Dave

1

Zakładając x jest pozytywny, mniej więcej tak:

angle = Math.Atan(y/x) * 180/Math.PI + 90 

Edited by umożliwić negatywnych x wartości:

Jeśli może być ujemna, tylko robić w każdym przypadku. Coś takiego:

if (x < 0) { 
    angle = 270 - (Math.Atan(y/-x) * 180/Math.PI); 
} else { 
    angle = 90 + (Math.Atan(y/x) * 180/Math.PI); 
} 
+0

Cóż X i Y mogą być dodatnie lub ujemne. – Dave

+2

Nie głosuj na niego, on tylko próbuje pomóc. – Dave

0
public static double GetAngleDegree(Point origin, Point target) { 
    var n = 270 - (Math.Atan2(origin.Y - target.Y, origin.X - target.X)) * 180/Math.PI; 
    return n % 360; 
} 

static void Main(string[] args) 
{ 
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(0, 3)));//0 
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(3, 0)));//90 
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(0, -3)));//180 
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(-3, 0)));//270 
} 
+1

Wygląda na to, że działa on w kierunku przeciwnym do ruchu wskazówek zegara, gdzie ** (0, 3) ** wynosi 0 stopni. – Dave

+0

Jest to idealne rozwiązanie do sortowania punktów pod kątem. –

0

Właściwie nie ma sposobu, aby dowiedzieć się kąt pomiędzy punktem i pochodzenia ze względu na fakt, że pochodzenie jest (0,0). Możemy obliczyć kąt między dwoma punktami, ponieważ są one traktowane jak wektory i jako takie mają kierunek, ale początek nie ma kierunku. Z tego powodu, jeśli chcesz znaleźć kąt na przykładzie zegara, możesz obliczyć kąt między punktem a (1,0), na przykład będąc tym punktem na 0 stopni.

przykro mi, że nie jestem biegły w C#, ale można spojrzeć na ten kod Java, który jest podobny:

double getAngle2PointsRad(double p1_x, double p1_y, double p2_x, double p2_y) { 
    return Math.acos((((p1_x * p2_x) + (p1_y * p2_y))/(Math.sqrt(Math.pow(p1_x, 2) + Math.pow(p1_y, 2)) * Math.sqrt(Math.pow(p2_x, 2) + Math.pow(p2_y, 2))))); 
} 

double getAngle2PointsDeg(double p1_x, double p1_y, double p2_x, double p2_y) { 
    return Math.acos((((p1_x * p2_x) + (p1_y * p2_y))/(Math.sqrt(Math.pow(p1_x, 2) + Math.pow(p1_y, 2)) * Math.sqrt(Math.pow(p2_x, 2) + Math.pow(p2_y, 2))))) * 180/Math.PI; 
} 

Jeśli próbujesz obliczyć stosując (0,0) dostaniesz NaN tak, próbuje podzielić przez zero.