20 Kasım 2018 Salı

Basit Shape Sınıfı - Daire

Giriş
Dairede pisagor teoremi çokça kullanılır. Basit bir daire sınıfı şöyledir.
class Circle {

private:

  double radius;  // Radius of circle

public:

  // Default constructor
  Circle() {
    radius = 0.0;
  }
  // Set the radius of the circle
  void setRadius(double r) {
    radius = r;
  }
  // Get the radius of the circle
  double getRadius() {
    return radius;
  }
  // Calculate the area of the circle using current radius
  double area() {
    return(3.1416 * radius * radius);
  }
};
Açıyı Normalize Etmek
Şöyle yaparız. Burda modulo arithmetic yani mod 360 eksi sonuç verebilir. Bu yüzden + 360 yapılarak düzeltiliyor.
this.orientation += degrees;

this.orientation = this.orientation % 360;

if (this.orientation < 0)
{
    this.orientation += 360;
}
Açı Farkı
[0 - 360] aralığındaki iki açının farkını verir. Şöyle yaparız.
float angleDifference = fmod(angle1 - angle2 + 900f, 360f) - 180f;
Açının İki Açı Arasında Olduğuna Bakmak
Şöyle yaparız.
static bool isABetween(int testAngle, int startAngle, int endAngle) {
  int endAngleDifference = Math.floorMod (endAngle - startAngle, 360);
  int testAngleDifference  = Math.floorMod (testAngle - startAngle, 360);

  return testAngleDifference <= endAngleDifference;

}
Açıyı Artırmak ve Küçültmek
Şöyle yaparız.
class CircularNumber{

  private static final int BOUND = 360;
  private int heading;

  public void add(int amt){
    header = (heading + amt) % BOUND;
  }

  public void deduct(int amt){
    header = (360 + heading - (amt % BOUND)) % BOUND;
  }
}
Açıyı X ve Y'ye Çevirmek
Şöyle yaparız. Açının Cos() sonucu X, Sin() sonucuY değerini verir.

Bir Noktanın Daire İçinde Olduğunu Anlama
Örnek
Şöyle yaparız.
boolean isPointInCircle(int clickX, int clickY) {
  return (clickX - x) * (clickX - x) + (clickY - y) * (clickY - y) <= radius * radius;
}
Örnek
first dairenin merkezi , second ise nokta olsun.
boolean isPointInside(Point second) {
  return (first.Center.Distance(second) <= radius;
}

Bir Dairenin Başka Bir Dairenin İçinde Olduğunu Anlama - overlap
Collision Detection yazısına taşıdım

Daireyi Eşit Olarak Dilimlere Bölme
Şöyle yaparız. r radius'u temsil eder. Burada sağ yatay eksenden yani trigonometrik 0 değerinden başlanıyor ve saatin tersine doğru dönülüyor.
//x0, y0 - center's coordinates
for(i = 1 to n)
{
    angle = i * (360/n);
    point.x = x0 + r * cos(angle);
    point.y = y0 + r * sin(angle);
}
Eğer Trigonometrik 180 yani sol eksenden başlamak isteseydik ve yine saatin tersi yönünde dönmek isteseydik şöyle yaparız.
x0 -=  cos(...)
y0 += sin(...)
Dairenin İçindeki Tüm Noktaları Bulmak
x ve y değerlerini bulmak için şöyle yaparız. x [-r,+r] aralığında olacak şekilde döngü kurarız. x^2 + y^ 2 = r^2 denklemini y'yi çözecek şekilde y = sqrt (r^2 - x^2) haline getiririz. Sonucu tam sayıya çevirmek için floor kullanıırz.
for x in [-floor(r), floor(r)]
    y_max = floor(sqrt(r^2 - x^2))    # Pythagora's theorem
    for y in [-y_max, y_max]
        # (x, y) is good !

Hiç yorum yok:

Yorum Gönder