在編程語言(Python,C#等)中,我需要確定如何計算線條與橫軸之間的角度?如何計算直線和橫軸之間的角度?
我認爲圖像描述了最好的,我想:
鑑於(P1 X,P1 ÿ)和(P2 X,P2 ÿ)是什麼計算這個角度的最好方法?起源在前面,只有正象限被使用。
在編程語言(Python,C#等)中,我需要確定如何計算線條與橫軸之間的角度?如何計算直線和橫軸之間的角度?
我認爲圖像描述了最好的,我想:
鑑於(P1 X,P1 ÿ)和(P2 X,P2 ÿ)是什麼計算這個角度的最好方法?起源在前面,只有正象限被使用。
首先找到起點和終點之間的差異(這裏,這是更多的有向線段,而不是「線」,因爲線無限延伸並且不在特定點開始)。
deltaY = P2_y - P1_y
deltaX = P2_x - P1_x
然後計算角度(從X軸正方向在P1
到正Y軸在P1
運行)。
angleInDegrees = arctan(deltaY/deltaX) * 180/PI
但是arctan
可能不是理想的,因爲將所述差異這種方式將擦除區分哪個象限的角度所需的區別是在(見下文)。改用如果你的語言包括atan2
功能如下:
angleInDegrees = atan2(deltaY, deltaX) * 180/PI
EDIT(2017年2月22日):在一般情況下,然而,呼籲atan2(deltaY,deltaX)
只是爲了得到正確的角度cos
和sin
可能是不雅。在這些情況下,您可以經常執行以下操作:
(deltaX, deltaY)
作爲向量。sqrt(deltaX*deltaX+deltaY*deltaY)
)劃分deltaX
和deltaY
,除非長度爲0deltaX
現在將是矢量和水平軸之間的角度的餘弦(從方向正數X到正數Y軸,位於P1
)。deltaY
現在將是該角度的正弦。EDIT(2017年2月28日):即使沒有正常化(deltaX, deltaY)
:
deltaX
符號會告訴你在步驟3中描述的餘弦值是正還是負。deltaY
的符號會告訴您步驟4中描述的正弦是正值還是負值。deltaX
和deltaY
跡象會告訴你哪個象限的角度在,相對於正X軸在P1
:
+deltaX
,+deltaY
:0至90度。-deltaX
,+deltaY
:90到180度。-deltaX
,-deltaY
:180至270度(-180至-90度)。+deltaX
,-deltaY
:270至360度(-90至0度)。使用弧度(由Eric Leschinski,誰編輯我的答案提供了2015年7月19日)在Python的實現:
from math import *
def angle_trunc(a):
while a < 0.0:
a += pi * 2
return a
def getAngleBetweenPoints(x_orig, y_orig, x_landmark, y_landmark):
deltaY = y_landmark - y_orig
deltaX = x_landmark - x_orig
return angle_trunc(atan2(deltaY, deltaX))
angle = getAngleBetweenPoints(5, 2, 1,4)
assert angle >= 0, "angle must be >= 0"
angle = getAngleBetweenPoints(1, 1, 2, 1)
assert angle == 0, "expecting angle to be 0"
angle = getAngleBetweenPoints(2, 1, 1, 1)
assert abs(pi - angle) <= 0.01, "expecting angle to be pi, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 3)
assert abs(angle - pi/2) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(2, 1, 2, 0)
assert abs(angle - (pi+pi/2)) <= 0.01, "expecting angle to be pi+pi/2, it is: " + str(angle)
angle = getAngleBetweenPoints(1, 1, 2, 2)
assert abs(angle - (pi/4)) <= 0.01, "expecting angle to be pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -2, -2)
assert abs(angle - (pi+pi/4)) <= 0.01, "expecting angle to be pi+pi/4, it is: " + str(angle)
angle = getAngleBetweenPoints(-1, -1, -1, 2)
assert abs(angle - (pi/2)) <= 0.01, "expecting angle to be pi/2, it is: " + str(angle)
對不起,但我很確定彼得的答案是錯誤的。請注意,y軸沿頁面向下(在圖形中常見)。因此,deltaY計算必須顛倒過來,否則你會得到錯誤的答案。
考慮:
System.out.println (Math.toDegrees(Math.atan2(1,1)));
System.out.println (Math.toDegrees(Math.atan2(-1,1)));
System.out.println (Math.toDegrees(Math.atan2(1,-1)));
System.out.println (Math.toDegrees(Math.atan2(-1,-1)));
給出
45.0
-45.0
135.0
-135.0
因此,如果在上述示例中,P1是(1,1),P2爲(2,2)[由於對Y增加了網頁],上面的代碼將給出45.0度的示例,這是錯誤的。更改deltaY計算的順序,它可以正常工作。
我按照你的建議反轉了它,並且我的旋轉反向。 –
如果您能夠以正確的方式顯示,那會很好。 –
在我的代碼中我修復了這個問題: 'double arc = Math.atan2(mouse.y - obj.getPy(),mouse.x - obj.getPx()); \t \t degrees = Math.toDegrees(arc); \t \t if(degrees <0) \t \t \t degrees + = 360; \t \t else if(度數> 360) \t \t \t degree - = 360; ' –
我發現了一個運行良好的Python解決方案!
from math import atan2,degrees
def GetAngleOfLineBetweenTwoPoints(p1, p2):
return degrees(atan2(p2 - p1, 1))
print GetAngleOfLineBetweenTwoPoints(1,3)
基於參考「彼得·」。這裏是java版本
private static final float angleBetweenPoints(PointF a, PointF b) {
float deltaY = b.y - a.y;
float deltaX = b.x - a.x;
return (float) (Math.atan2(deltaY, deltaX)); }
考慮確切的問題,把我們在一個「特殊」的地方正軸指向下移動座標系(如的屏幕或接口視圖),則需要適應這樣的這個功能,和負的Y座標:
實施例中夫特2.0
func angle_between_two_points(pa:CGPoint,pb:CGPoint)->Double{
let deltaY:Double = (Double(-pb.y) - Double(-pa.y))
let deltaX:Double = (Double(pb.x) - Double(pa.x))
var a = atan2(deltaY,deltaX)
while a < 0.0 {
a = a + M_PI*2
}
return a
}
此功能給出了正確的答案。答案是弧度,這樣的使用情況,以度視角,方法是:
let p1 = CGPoint(x: 1.5, y: 2) //estimated coords of p1 in question
let p2 = CGPoint(x: 2, y : 3) //estimated coords of p2 in question
print(angle_between_two_points(p1, pb: p2)/(M_PI/180))
//returns 296.56
deltaY = Math.Abs(P2.y - P1.y);
deltaX = Math.Abs(P2.x - P1.x);
angleInDegrees = Math.atan2(deltaY, deltaX) * 180/PI
if(p2.y > p1.y) // Second point is lower than first, angle goes down (180-360)
{
if(p2.x < p1.x)//Second point is to the left of first (180-270)
angleInDegrees += 180;
else (270-360)
angleInDegrees += 270;
}
else if (p2.x < p1.x) //Second point is top left of first (90-180)
angleInDegrees += 90;
matlab函數:
function [lineAngle] = getLineAngle(x1, y1, x2, y2)
deltaY = y2 - y1;
deltaX = x2 - x1;
lineAngle = rad2deg(atan2(deltaY, deltaX));
if deltaY < 0
lineAngle = lineAngle + 360;
end
end
如果您發現了這一點,你是通過JavaScript這是非常重要的注意Math.sin和Math。cos採用弧度,因此您無需將結果轉換爲度數!所以忽略* 180/PI位。 花了我4個小時才發現。 :) – sidonaldson
應該用什麼來計算沿垂直軸的角度? – ZeMoon
@akashg:'90 - angleInDegrees'? – jbaums