2010-06-30 32 views
7

Tôi muốn biết cách lấy một góc của đường A-B từ trục ngang X. Các câu hỏi khác trong SO làm điều đó chỉ giữa hai dòng. Tôi biết rằng tôi luôn có thể vẽ dòng A-C thứ hai và tính toán nhưng tôi tự hỏi nếu có phương pháp nhanh hơn.lấy góc của một đường từ chân trời

EDIT: Tôi rất chắc chắn tôi không thực hiện tối ưu hóa sớm.

+2

Hãy cảnh giác với tối ưu hóa sớm. Bạn đã lược tả mã chưa? –

+1

Tôi không thể hiểu số phiếu bầu xuống. Đây có phải là một câu hỏi ngớ ngẩn không? hoặc là nếu gây khó chịu? hmm .. – VOX

+1

@VOX - Đăng kết quả lược tả của bạn. Chứng minh cho bản thân rằng bạn cần một giải pháp nhanh hơn. –

Trả lời

9

Bạn có thể sử dụng atan cho điều đó.

angle = atan((By-Ay)/(Bx-Ax)) 
0

Trục x thực sự là một phù hợp với phương trình

y = 0

vì vậy bạn có thể sử dụng giải pháp bạn có rồi.

+0

Tôi đang tìm phương pháp nhanh hơn (ít cpu) hơn nếu có. – VOX

1

Nếu

  1. Góc nhỏ,
  2. bạn có thể sống những thông tin sai nhỏ, và
  3. Bạn có thể sử dụng các góc theo radian và không độ,

sau đó có một giải pháp nhanh: Trong những điều kiện này, bạn có thể giả định rằng tan (a) = a = atan (a), và do đó chỉ bỏ qua lệnh atan().

+0

cảm ơn vì một điểm tốt. – VOX

+0

"tan (a) = a = atan (a)" Eh ... cái gì? –

+0

@Bart van Heukelom: Vâng, như tôi đã viết, điều này là không chính xác, nhưng một xấp xỉ tốt cho các góc nhỏ. E. g. tan (0.1) = 0.1003, tan (0.2) = 0.203 Vì vậy, đối với các góc trong phạm vi này, nếu bạn không cần độ chính xác tuyệt đối, bạn có thể tiết kiệm một số nỗ lực tính toán. – Frank

1

Bạn cũng có thể sử dụng arccosine, nếu dòng của bạn ở dạng [r_x,r_y], trong đó r_x là thay đổi trong x và r_y là thay đổi trong y.

angle = arccos(r_x/(r_x*r_x + r_y*r_y)) 

Nó hơi đục hơn, nhưng đó là cơ bản của pháp luật về chấm sản phẩm:

angle = arccos (r . v) 

đâu rv đều vectơ đơn vị (vectơ có độ dài 1). Trong trường hợp của chúng tôi, v là vector [1,0], và r là

[r_x,r_y]/(r_x^2+r_y^2) 

để làm cho nó một vector đơn vị.

6
private double Angulo(int x1, int y1, int x2, int y2) 
    { 
     double degrees; 

     // Avoid divide by zero run values. 
     if (x2 - x1 == 0) 
     { 
      if (y2 > y1) 
       degrees = 90; 
      else 
       degrees = 270; 
     } 
     else 
     { 
      // Calculate angle from offset. 
      double riseoverrun = (double)(y2 - y1)/(double)(x2 - x1); 
      double radians = Math.Atan(riseoverrun); 
      degrees = radians * ((double)180/Math.PI); 

      // Handle quadrant specific transformations.  
      if ((x2 - x1) < 0 || (y2 - y1) < 0) 
       degrees += 180; 
      if ((x2 - x1) > 0 && (y2 - y1) < 0) 
       degrees -= 180; 
      if (degrees < 0) 
       degrees += 360; 
     } 
     return degrees; 
    } 
0

Nếu bạn cần tất cả bốn phần tư, Atan2 phù hợp hơn Atan.

public static int GetAngleBetweenPoints(PointF pt1, PointF pt2) 
{ 
    float dx = pt2.X - pt1.X; 
    float dy = pt2.Y - pt1.Y; 

    int deg = Convert.ToInt32(Math.Atan2(dy, dx) * (180/Math.PI)); 
    if (deg < 0) { deg += 360; } 

    return deg; 
} 
Các vấn đề liên quan