Bir nesnenin bağlı bir yolun etrafında CW veya CCW taşıdığını nasıl anlayabilirim?


19

Diyelim ki pürüzlü bir şekle sahibiz:

shape0

Ve iki yaratık onun çizgisi boyunca hareket ediyor.

Sonra köşeleri dışarı çekerek şekli tamamen düzeltiriz.

Bunu elde ederiz:

pürüzsüz

Portakal'ın CW ve yeşil CCW'yi hareket ettirdiğini görmek artık çok kolay. Şekli düzeltmeden hangi yönde hareket ettiklerini nasıl anlayabilirim?

Yeni görüntü

resim açıklamasını buraya girin


İşte 2 sentim
Kendall Frey

Yanıtlar:


27

Sonsuza kadar bir çizgi çizin ve yaratığın bulunduğu segmenti saymadan şekli kaç kez (çift veya tek) geçtiğinizi sayın. Ardından, yaratığın o çizginin sağına mı yoksa sağına mı gittiğini kontrol edin.

misal

Bu örnekte, şekli iki kez (hatta çift) geçiyoruz ve sola gidiyoruz. Sonuç şu tablodan hemen çıkar:

   # Crosses | even  | odd
  Direction  |       |
-------------+-------+------
    left     | CCW   |  CW
    right    |  CW   | CCW

Sözde kodda:

x, y = position of creature
vx, vy = direction of creature movement
crossings = 0
for each x1, y1, x2, y2 in shape segments:
    if (x1 < x and x <= x2) or (x2 < x and x <= x1):
        if y - y1 > (x - x1) * (y2 - y1) / (x2 - x1):
            ++crossings
if (crossings & 1) == (vx < 0):
    return CW
else
    return CCW

devam eden çizgi canlısını ekliyor musun?
Ali1S232

@Gajoo: hayır, bu nedenle> 6 satırında> = yerine> bununla ilgili bir not ekleyeceğim. Ancak, satırı ekleyebileceğinizi ve yalnızca tablo içeriğini ters çevirebileceğinizi unutmayın.
sam hocevar

1
Bu yönteme dayanarak bir cevap vermekle verdiğim cevap arasında savundum. Burada her iki yaklaşımı temsil ettiğimiz için mutluyum. Bu, kavramsal olarak daha basit ve çok zariftir, ancak sağlam hale getirmek zor olabilen çizgi segmenti kavşak testleri gerçekleştirmeyi gerektirir.
Trevor Powell

@TrevorPowell Doğru. En uzak kenarı bulmak kafa karıştırıcı olabilir. Önce kenarın en uzak köşesine göre kontrol ettim ve sonra şeklin merkezinden ve iki kenarın merkezinden (tepe noktasını paylaşan ikisi) bir çizgi çizerek ve çizgilerden birinin başka bir kenarı geçip geçmediğini görerek Bu kenarlardan birini geçtikten sonra sonsuzluk. Tamam çalıştı
wolfdawn

5

Bu, şekil veri yapınızdan hangi bilgilere sahip olduğunuza bağlıdır, ancak bir şeklin anahattı boyunca hareket eden bir yaratık her zaman sağ taraftaki şeklin iç kısmına sahip olacak ve CCW'yi hareket ettiren bir yaratık şeklin içine onun sol.


Çok daha basit bir çözüm ve aynı zamanda ilk düşüncem.
Amplify91

şeklin içinde hangi yönün olduğunu nasıl anlarsınız? Yani şeklin içindeki bir kenar boyunca hareket etmek ya solunuzda ya da sağınızda. bunun nasıl olduğunu nereden biliyorsun?
Ali1S232

Çok zarif bir çözüm, ancak genel olarak doğru değil. İki boyutlu bir şekil yapmak için bir masaya yaslanmış bir çörek hayal edin. Bu şeklin kenarı boyunca yürüyebilir, şeklin içini solunuzda tutabilir ve başladığınıza bağlı olarak saat yönünde veya saat yönünün tersine bir tur yapabilirsiniz.
Marcks Thomas

4
  1. Şeklinizin merkez noktasını hesaplayın.
  2. Merkezinizden şeklin en uzak kenarını seçin.
    • (En uzak kenarı seçmek, şeklin ters, içbükey bir kısmından başlamamanızı sağlar, bu da tüm şekil için saat yönünde / saat yönünün tersine belirlemesini sağlar)
  3. Bu kenar boyunca hangi yönün saat yönünde olduğunu belirleyin
    • (Bunun basit bir uygulaması, şeklin merkezinden seçilen kenarın her bir ucuna olan açıların karşılaştırılmasını içerir. Açılar arasındaki farkın işareti saat yönünde veya saat yönünün tersine söyler)
  4. 2. adımda seçtiğiniz kenardan başlayarak, kenarların bir listesini oluşturarak şeklin tüm kenarları üzerinde yineleyin. Her kenar için iki köşesini saat yönünde saklayın.
    • (Şekliniz zaman içinde değişmiyorsa, bu kenar listesini daha sonra kullanmak üzere saklayabilirsiniz, böylece her karede ilk dört adımı yapmanız gerekmez)
    • (zaten bir kenar listeniz olabilir. Öyleyse, bu saat yönünde tepe sırasını aynı listede saklayabilirsiniz.)
  5. Bir varlığın saat yönünde mi yoksa saat yönünün tersine mi hareket ettiğini belirlemek için:
    • Varlığın hangi kenarı hareket ettirdiğini belirleyin.
    • 4. adımda belirlediğiniz kenarın saat yönünde başlangıç ​​- bitiş köşelerinden objenin vektöre karşı hareket yönünün bir nokta ürününü yapın.
    • Nokta ürününün sonucu sıfırdan büyük bir değerse, varlık saat yönünde hareket eder. Sıfırdan küçük, saat yönünün tersine anlamına gelir.

Çok akıllıca cevap
wolfdawn

Küçük bir sorum mu var? şeklindeki köşelerin en sol CWW noktasından başlayarak numaralandırıldığını varsayarsak, cevabınıza göre 6-> 7 veya 9-> 10 (sıfır temelli) hareketin saat yönünde hareket edip etmediğini nasıl anlayabilirim?
Ali1S232

En uzak kenardan başlıyorsunuz ve o kenarda hangi yolun saat yönünde olduğunu anlıyorsunuz. Diyelim ki A kenarı 'a' ila 'b' tepe noktasında saat yönünde. Daha sonra B kenarına hareket edersek ('b' ve 'c' köşeleri vardır), B'nin 'b' den 'c' ye saat yönünde olduğunu biliyoruz. Benzer şekilde, C kenarı 'c' den 'd' ye doğru saat yönünde olacaktır. Bir kenardan doğru saat yönünü bildiğimizde (1-3 arası adımlar), şeklin kenarları etrafında bu saat yönünde devam ederek, kenarlarının bulunduğu yere bakmadan her kenar için doğru 'saat yönünde' sonucunu çıkarabiliriz, böylece içbükey tamam.
Trevor Powell

A kenarının 'a' ile 'b' arasında saat yönünde olup olmadığını veya 'b' ile 'a' arasında saat yönünde olup olmadığını nasıl anlarsınız? Bence o kısmı kaçırdın.
Ali1S232

@ Gajoo Bu 3. adımdaki parantez noktasıdır. Muhtemelen parantez olmamalıdır, çünkü bu gerçekten tüm sürecin kritik adımıdır.
Trevor Powell

2

Çokgenin hangi yönde tanımlandığını, köşelerin hangi yönde döndüğünü bilmeniz gerekir.

Bunu bilmiyorsanız, çokgenin alanını hesaplayarak çalışabilirsiniz:

float Polygon::area() {
    float result = 0.0f;

    for(int a = 0; a < vertexCount; a ++) {
        int b = (a+1) % vertexCount;
        result += vertices[a].x * vertices[b].y;
        result -= vertices[a].y * vertices[b].x;
    }

    return result * .5f;
}

İşareti sonuç (pozitif veya negatif) saat yönünde veya saat yönünün tersine olup olmadığını söyleyecektir arasında. Koordinat sisteminize bağlı olduğu için sizin için hangi yönde olduğunu görmek için bunu denemeniz gerekir.

Şekil saat yönünde ise:

  • Şeklin etrafında ilerleyen bir yaratık saat yönünde gidiyor ve
  • Şekle geri dönen bir yaratık saat yönünün tersine gidiyor .

Şekil saat yönünün tersine ise:

  • Şeklin etrafında ilerleyen bir yaratık saat yönünün tersine gidiyor ve
  • Şekle geri dönen bir yaratık saat yönünde gidiyor .

0

Görünüşe göre Trevor bu soruyu zaten ele aldı, ama işte benim çözümüm:

  1. şeklinizin kapladığı alanı hesaplayın, yani

    area = 0
    foreach (edge in shape)
        area += edge.begin.x * edge.end.y - edge.begin.y * edge.end.x
  2. yukarıdaki gibi hesaplanan alanı kullanarak şeklin kendisinin saat yönünde olup olmadığını kolayca anlayabilirsiniz. yalnızca alan sıfırın altındaysa saat yönünde.

  3. nesnelerin köşe noktaları ile aynı şekilde mi yoksa ters yönde mi hareket ettiğini kontrol edin.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.