13 Kasım 2017 Pazartesi

atan2 metodu - Y ve X'ten Açıyı Hesaplar

Giriş
İmzası şöyle
double atan2( double y, double x );
atan2 Y,X değerlerini kullanarak X eksene göre açıyı hesaplar ve [-PI, PI] arasında bir değer döner. Bu değerler [0 - 360] dereceye tekabül eder. Yani tüm daire için kullanılabilir.

atan ile ilişkisi
Sadece 1 ve 4 numaralı çeyrekler için kullanılır
Quadrant    Angle              
-------------------------------
  I           0    < α < π/2   
  II          π/2  < α < π     
  III         π    < α < 3π/2  
  IV          3π/2 < α < 2π    
tangent (tanjant) ile ilişkisi
Açıklaması şöyle. atan2'de y ve x'ten açıya gidiyoruz. tanjant'ta açıdan x'e gidiyoruz.
let θ be arctanx, so that tan⁡θ=x.
atan2 değerini normalleştirme [0,2PI] arasına getirme
Eğer atan2 sonucu eksi ise ve [0,2PI) arasında bir değer elde etmek istiyorsak şöyle yaparız.
if(theta <0)
  theta = Math.PI - theta;
veya
if(theta <0)
  theta = (2 * Math.PI) - theta; //2PI + theta
x eksenine göre saatin tersi yönünde açıyı hesaplama
atan2 (y,x) x eksenine göre saatin tersin yönünde açıyı hesaplar. Şekilde bunu görebiliriz. Eğer başlangıç noktasını dairenin merkezi kabul edersek aşağıdaki formülü kullanabiliriz.
float angle = atan2(y_handle - y_center, x_handle - x_center);
Açıyı dereceye çevirmek istersek şöyle yaparız.
double angleFromX = atan2(deltaY, deltaX);
double angle = M_PI - angleFromX;
double angleInDegrees = 180 * angle / M_PI;
C# dili ile Vector sınıfının AngleBetween() metodunu kullanarak açıyı bulmak ta mümkün.
Yukarıda anlatılan işlemde x,y kartezyen noktalarından açıyı bulduk. Aslında yaptığımız şey kartezyen sistemden, trigonometrik sisteme geçişti. Bu geçişleri formül haline getiren yazıyı Converting between Polar and Cartesian Coordinates yazısında bulabilirsiniz. Kısaca trigonometrik sistemde r harfi yarıçapı, teta ise açıyı belirtir. Kartezyen sistemde ise x ve y konumları belirtir. Aşağıdaki şekilde görülebilir.
Geçiş için kullanılan formül ise çok kolay.

x eksenine göre açının hangi çeyreğe düştüğünü hesaplama
Şöyle yaparız.
int sliceIndex(double xx, double yy, double x, double y, int nSlices) {
  double angle = Math.atan2(yy - y, xx - x);
  double sliceAngle = 2.0 * Math.PI / nSlices;
  return (int) (angle / sliceAngle);
}
y eksenine göre saatin tersi yönünde açıyı hesaplama
Eğer atan2(x,y) şeklinde kullanırsak y eksenine göre açıyı hesaplar. Şekilde bunu görebiliriz.

y eksenine göre saat yönünde (pusula yönü) açıyı hesaplama
Uçakta veya kartezyen koordinat sisteminde yaw (yan dönme açısını) değerini hesaplamak için kullanılabilir.
Örnek
Şöyle yaparız. Eski değerle karşılaşmamızın sebebi atan2() çağrısının -PI dönebilmesi.
double angleInRadians = Math.Atan2(y, x);
double angleInDegrees = (180 / Math.PI) * angleInRadians;
//this angle measures anti-clockwise from "east". To convert this to an angle that
//measures clockwise from "north":
double compassRadians = Math.PI / 2 - angleInRadians;
double compassDegrees = (180 / Math.PI) * compassRadians;

//but now we may encounter negative values, so we can normalize them with the following //method:
double normalizeDegrees(double a) => ((a % 360) + 360) % 360; //convert to 0-360

var compassAngle = normalizeDegrees(compassDegrees);

atan2 alternatifi
Eğer atan2 kütüphanemizde yoksa buradaki soruda da anlatıldığı gibi aşağıdaki formül kullanılabilir.
atan2(deltaY, deltaX) = arctan(deltaY / deltaX)
atan2 ve hue (rengin özü)
HSV renk uzayı için buraya bakabilirsiniz. hue kullanan renk sistemi aşağıda. hue açısal bir değerdir ve 0-360 arasında değişir. Buradaki soruda yan yana bulunan renk özlerinin ortalamasını bulmak için atan2 fonksiyonunu kullanımı gösterilmiş.

Hiç yorum yok:

Yorum Gönder