programing

선과 수평축 사이의 각도는 어떻게 계산하나요?

newsource 2022. 9. 22. 00:26

선과 수평축 사이의 각도는 어떻게 계산하나요?

프로그래밍 언어(Python, C# 등)에서는 선과 수평축 사이의 각도를 계산하는 방법을 결정해야 합니다.

이미지가 내가 원하는 것을 가장 잘 묘사한다고 생각한다.

어떤 말로도 이것을 설명할 수 없다

주어진x (P1y, P1) 및x (P2y, P2)에서 이 각도를 계산하는 가장 좋은 방법은 무엇입니까?원점은 왼쪽 상단에 있으며 양의 사분면만 사용됩니다.

먼저 시작점과 끝점 사이의 차이를 찾습니다(여기서는 선이 무한히 연장되고 특정 지점에서 시작되지 않으므로 "선"이 아니라 유향선 세그먼트에 가깝습니다).

deltaY = P2_y - P1_y
deltaX = P2_x - P1_x

그런 다음 각도(양수 X축에서 다음 위치에 있음)를 계산합니다.P1 Y축에 Y축의 Y축의 Y축에 P1를 참조해 주세요.

angleInDegrees = arctan(deltaY / deltaX) * 180 / PI

★★★★★★★★★★★★★★★★★.arctan이 방법으로 차이를 나누면 각도가 어느 사분면에 있는지를 구별하는 데 필요한 구분이 지워지기 때문에 이상적이지 않을 수 있습니다(아래 참조).언어를 사용하는 경우 대신 다음을 사용하십시오.atan2★★★★

angleInDegrees = atan2(deltaY, deltaX) * 180 / PI

(2017년 2월 ) : 으로는 발신자, 발신자atan2(deltaY,deltaX) cos ★★★★★★★★★★★★★★★★★」sin'다음에 하다'라는 말을 대신 다음과 같은 을 할 수 있습니다.

  1. (deltaX, deltaY)벡터로서.
  2. 그 벡터를 단위 벡터로 정규화한다.나누려면 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .deltaX ★★★★★★★★★★★★★★★★★」deltaY벡터 길이(sqrt(deltaX*deltaX+deltaY*deltaY)'0'입니다.
  3. 후 ★★★★★★★★★★★★★★★★★.deltaX)이 .P1를 참조해 주세요.
  4. ★★★★★★★★★★★★★★★★★.deltaY이제 그 각도의 사인(sine)이 됩니다.
  5. 벡터의 길이가 0인 경우 벡터와 수평축 사이에 각도가 없기 때문에 유의한 사인 및 코사인 값이 없습니다.

(2017년 2월 ) : 정규화되지 않은 (deltaX, deltaY):

  • ★★★★★★★★★★★★★★★★의 기호deltaX그럼 스텝 3에서 설명한 코사인 값이 양의 값인지 음의 값인지를 나타냅니다.
  • ★★★★★★★★★★★★★★★★의 기호deltaY음의 값인지를 .4단계에서 설명한 사인 값이 양의 값인지 음의 값인지를 알려줍니다.
  • ★★★★★★★★★★★★★★★★의 기호deltaX ★★★★★★★★★★★★★★★★★」deltaY가 어느, 즉 각도가 어느 사분면에 있는지 줍니다.P1다음과 같습니다.
    • +deltaX,+deltaY: 0 ~ 90 °
    • -deltaX,+deltaY: 90 ~ 180 °C
    • -deltaX,-deltaY: 180 ~ 270 °C (-180 ~ -90 °C )
    • +deltaX,-deltaY: 270~360(90~0)

라디안을 사용한 Python 구현(2015년 7월 19일 Eric Leschinski 제공)

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)

모든 테스트 통과.https://en.wikipedia.org/wiki/Unit_circle 를 참조해 주세요.

미안한데, 피터의 답은 틀렸을 거야.Y축은 페이지 아래쪽으로 이동합니다(그래픽에서 공통).따라서 델타Y 계산을 반대로 하지 않으면 잘못된 답을 얻을 수 있습니다.

고려사항:

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도를 나타냅니다.이것은 잘못된 것입니다.델타Y 계산 순서를 변경하면 올바르게 동작합니다.

import math
from collections import namedtuple


Point = namedtuple("Point", ["x", "y"])


def get_angle(p1: Point, p2: Point) -> float:
    """Get the angle of this line with the horizontal axis."""
    dx = p2.x - p1.x
    dy = p2.y - p1.y
    theta = math.atan2(dy, dx)
    angle = math.degrees(theta)  # angle is in (-180, 180]
    if angle < 0:
        angle = 360 + angle
    return angle

테스트

테스트를 위해 가설이 테스트 케이스를 생성하도록 하겠습니다.

여기에 이미지 설명 입력

import hypothesis.strategies as s
from hypothesis import given


@given(s.floats(min_value=0.0, max_value=360.0))
def test_angle(angle: float):
    epsilon = 0.0001
    x = math.cos(math.radians(angle))
    y = math.sin(math.radians(angle))
    p1 = Point(0, 0)
    p2 = Point(x, y)
    assert abs(get_angle(p1, p2) - angle) < epsilon

Python에서 잘 작동하는 솔루션을 찾았습니다!

from math import atan2,degrees

def GetAngleOfLineBetweenTwoPoints(p1, p2):
    return degrees(atan2(p2 - p1, 1))

print GetAngleOfLineBetweenTwoPoints(1,3)

'피터 O'에 따르면..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 좌표를 음수화해야 합니다.

Swift 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

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

0 ~ 2pi의 각도에 대한 공식입니다.

x=x2-x1과 y=y2-y1이 있습니다.이 공식은 다음과 같은 경우에 유효합니다.

x와 y의 임의의 값.x=y=0의 경우 결과가 정의되지 않습니다.

f(x,y)=pi()-pi()/2*(1+sign(x)*(1-sign(y^2)))

     -pi()/4*(2+sign(x))*sign(y)

     -sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
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;

언급URL : https://stackoverflow.com/questions/7586063/how-to-calculate-the-angle-between-a-line-and-the-horizontal-axis