Hızlı hareket eden nesneler için altıgen çarpışma algılama?


39

Bir nesnenin bir konumu ve hız vektörü vardır. Genellikle sadece konum, iki nesnenin çarpışıp çarpışmadığını kontrol etmek için kullanılır, bu çok hızlı hareket eden nesneler için problemlidir, çünkü nesnenin ilk çarpışma kontrolünde ve arkasındaki ilk nesnenin önünde olduğu kadar hızlı hareket etmesi olasıdır. ikinci çarpışma kontrolü.

Sınırlama Kutusu Çarpışma Başarısız

Şimdi, sadece her nesnenin hareket vektörünün diğerinin sınırlama kutusuyla kesişip kesiştiğini kontrol ettiğiniz çizgi tabanlı çarpışma kontrolleri de var. Bu bir noktanın genişlemesi olarak görülebilir. Bu, yalnızca hızlı hareket eden nesnenin gerçekten küçük olması durumunda çalışır.

Altıgen Çarpışma Kazandı

Öyleyse benim fikrim, bir noktayı genişletmek yerine neden bir dikdörtgeni genişletmemek. Bu bir Altıgen ile sonuçlanır.

Şimdi, şimdiye kadar çok iyi. Fakat bu tip iki Hexagon'un kesişip kesişmediğini nasıl kontrol edebilirim? Bunların çok özel Hexagon'un olduğuna dikkat edin.

Altıgen Özellikler

Bonus Soru : Çarpmanın nerede olduğunu (veya ne kadar zaman sonra) tam olarak hesaplamak mümkün mü? Bu, gerçekte ne olduğunu, nerede ve ne kadar güçle olduğu ve çarpışma ile çerçevenin sonu arasındaki sürede nasıl hareket ettiklerini simüle etmek gibi çok yararlı olabilir.


(A satırındaki) için (B satırındaki) için (satırlar arası) çarpışma - bunun dışında A durumunda B veya B'yi kapsamaz. Hm. =)
Jari Komppa

4
Kutulara bağlı mısın? Çektiğiniz kutular, minimum hassasiyet kaybı fakat nispeten kolay bir çarpışma algosuyla çevrelerle temsil edilebilir. Kaydırılmış daire çarpışma tespitini arayın. Uzunluk / genişlik oranınız 1'den uzaklaşırsa, bu kadar çekici olmaz.
Steve H,

@SteveH En esnek çözümü arıyorum, bu yüzden uzunluk / genişlik oranı oldukça fazla.
API-Canavar

1
Sadece altıgenlerin kesiştiğinin çarpışmanın gerçekleştiği anlamına gelmediğini anlamalısınız. Yanlışlıkla kesişip çarpışmadıklarını söyleyebilseniz bile, çarpışmanın olup olmadığını ve açıkça ve nerede ve ne zaman olacağını belirlemek için yine de çalışmanız gerekir. Yani henüz bonus sorunuza atlayamazsınız.
jrsala

2
Bunu daha önce denemedim, ancak 2d uzayındaki altıgenler yerine, 2d'deki hareketi bir eksenin zaman olduğu 3B uzayda hacim olarak düşünebilirsiniz. Daha sonra (3, 3) koordinatlarıyla iki 3 boyutlu polihedrayı kesiyorsunuz. İki katı nesne kesişirse, minimum t değerini bulmak istersiniz. Tüm B koordinatlarını A'nın referans çerçevesinde olacak şekilde dönüştürerek biraz sadeleştirebilirsiniz. Bunu henüz uygulamadım ama başlayacağım yer burası.
sabah

Yanıtlar:


34

Çözüm aslında beklenenden daha basittir. İşin püf noktası , altıgen tekniğinizden önce Minkowski çıkartmasını kullanmaktır .

İşte A ve B dikdörtgenlerin, hızları vAve vB. Not olduğunu vAve vBaslında olmayan hızlar, bunlar mesafe tek bir karede sırasında gitti.

Aşama 1

Şimdi, B dikdörtgenini P noktasıyla değiştirin ve A dikdörtgenini A ve B boyutlarının toplamına sahip C = A + (- B) dikdörtgeniyle değiştirin. Minkowski ekleme özellikleri, nokta ile yeni dikdörtgen arasında çarpışma gerçekleştiğini belirtir. ve sadece orijinal iki dikdörtgen arasında çarpışma meydana gelirse:

Adım 2

Fakat eğer dikdörtgen C vektör boyunca hareket ederse vAve P noktası vektör boyunca hareket ederse vB, basit bir referans çerçevesi değişikliği bize C dikdörtgeninin hala olduğu gibi olduğunu ve P noktasının vektör boyunca hareket ettiğini söyler vB-vA:

Aşama 3

Ardından, yeni referans çerçevesinde çarpışmanın nerede olduğunu anlatmak için basit bir kutu kesimi kesişim formülü kullanabilirsiniz.

Son adım uygun referans çerçevesine geri dönmek. Sadece nokta tarafından kat edilen mesafeyi vektör uzunluğu ile daire içine vB-vAalınacak şekilde kesişene kadar bölün ve sböyle bir değer elde edersiniz 0 < s < 1. Çarpışma, karenizin süresinin s * Tolduğu zaman olur T.

Madshogo tarafından yapılan açıklama :
Bu tekniğin Bay Beast'in cevabındakilere göre çok büyük bir avantajı, eğer dönme olmazsa, "Minkowski çıkarma" A + (- B) sonraki tüm zaman aşımları için bir kez hesaplanabilir !

Tüm bunlarda zaman alan tek algoritma (Minkowski toplamı, karmaşıklığın O (mn) olduğu, m'nin A'daki köşe sayısı ve n'deki B'deki köşe sayısı ) yalnızca bir kez kullanılabilir, çarpışma algılamasını etkin bir şekilde sabit hale getirir. zaman sorunu!

Daha sonra, A ve B'nin sahnenizin farklı bölümlerinde olduğundan emin olduktan sonra (dörtlü'nüzün?) Toplamı bir kenara atabilirsiniz ve artık çarpışmayacaksınız.

Buna karşılık, Bay Beast'un metodu her zaman adımında oldukça fazla hesaplama gerektiriyor.

Ayrıca, eksen hizalı dikdörtgenler için, A + (- B) , tüm toplamları hesaplamaktan çok daha basit bir şekilde hesaplanabilir; B yüksekliğini B yüksekliğini ve genişliğini B genişliğini ekleyerek A'yı genişletin (her iki tarafta bir buçuk).

Ancak tüm bunlar sadece ne A ne de B dönmediğinde ve her ikisi de dışbükey ise işe yarar . Dönme varsa veya içbükey şekiller kullanıyorsanız, süpürülmüş birimler / alanlar kullanmanız gerekir.
yorumun sonu


4
Oldukça ilginç bir yaklaşım gibi gözükse de, henüz% 100 anlamadım, nesne gerçekten küçük olduğunda ve iki satır arasında hareket ettiğinde ne olur? i.imgur.com/hRolvAF.png
API-Canavar

-1: Bu yöntem hiçbir şekilde çarpışmanın gerçekleştiğinden emin olmanıza izin vermez. Bu sadece emin olmasını sağlar gelmez segmenti ve haddelenmiş hacim yapmak durumunda gerçekleşmesi değil kesiştiği. Ancak kesişmeleri ve çarpışma olmaması tamamen mümkündür. Yanlış olan, "Şimdi [...] çarpışmanın nerede gerçekleştiğine karar vermek için basit segment segmenti kesişimini kullanabilirsiniz" kısmıdır.
jrsala

2
@madshogo Haklısın. Timestep'in bunun problem olmayacağı nesne boyutlarına göre yeterince küçük olduğunu varsaydım, ancak genel durum için kesinlikle çok sağlam değil. Tamir etmeye bakacağım.
sam hocevar

@ SamHocevar Eğer cevap büyük olurdu olurdu gözden geçirebilirseniz.
API-Canavar

1
Evet ve hayır @LuisAlves ... tüm mantık çalışır, ancak değiştirmek gerekecek vB-vAile g(t)-f(t)nerede fve gzaman içinde A ve B pozisyonları bulunmaktadır. Bu artık düz bir çizgi olmadığı için kutu-parametrik eğri kesişme problemini çözmeniz gerekecektir.
sam hocevar

17

Öncelikle, eksen hizalı dikdörtgenler söz konusu olduğunda Kevin Reid'in cevabı en iyisi ve algoritması en hızlısı.

İkinci olarak, basit şekiller için, çarpışma tespiti için nispi hızları (aşağıda görüldüğü gibi) ve ayırma ekseni teoremini kullanın. Bu olacak bir çarpışma doğrusal hareket (devir yok) durumunda olur olmadığını bildirir. Ve rotasyon varsa, hassas olması için küçük bir zaman adımına ihtiyacınız vardır. Şimdi soruyu cevaplamak için:


Genel durumda, iki dışbükey şeklin kesiştiği nasıl anlaşılır?

Size sadece altıgenler için değil tüm dışbükey şekiller için çalışan bir algoritma vereceğim.

X ve Y'nin iki dışbükey şekil olduğunu varsayalım . Bunlar ortak bir nokta vardır, ancak ve ancak bir nokta vardır, yani, kesişen x X ve nokta y ∈ Y , örneğin , X = Y . Eğer boşluğu bir vektör boşluğu olarak görürseniz, bu x - y = 0 demek anlamına gelir . Ve şimdi bu Minkowski işine gidelim:

Minkowsky toplamı ve X ve Y her kümesidir , x + y için x ∈ X ve y ∈ Y .


X ve Y için bir örnek


X, Y ve Minkowski toplamı, X + Y

Diyelim (= Y) her bir grubu olduğu -y için y ∈ Y , bir önceki paragrafa verilen X ve Y, kesiştiği ancak ve ancak X + (= Y) içeren 0 , kökenli, .

Yan açıklama: neden X - Y yerine X + (-Y) yazıyorum ? Çünkü matematikte, bazen X - Y yazılı olan A ve B'nin Minkowski farkı olarak adlandırılan bir işlem var, ancak x - X ve y ∈ Y için tüm x - y kümeleriyle hiçbir ilgisi yoktur (gerçek Minkowski) fark biraz daha karmaşıktır).

Bu yüzden Minkowski'nin X ve -Y toplamlarını hesaplamak ve bunun kökenini içerip içermediğini bulmak istiyoruz. Köken, herhangi bir noktaya kıyasla özel değildir, bu nedenle orijinin belirli bir etki alanı içinde olup olmadığını bulmak için, bize verilen herhangi bir noktanın o etki alanına ait olup olmadığını söyleyebilecek bir algoritma kullanırız.

Minkowski toplamı X ve Y ise ki serin özelliğine sahiptir X ve Y, konveks, daha sonra X + Y too. Ve bir noktanın dışbükey bir kümeye ait olup olmadığını bulmak, o kümenin dışbükey olmadığından çok daha kolaydır.

X - X ve y ∈ Y için tüm x - y değerlerini hesaplayamayız çünkü x ve y noktalarının sonsuzluğu vardır, umarım, X , Y ve X + Y dışbükey olduğundan, sadece kullanabiliriz "en dıştaki" , köşeleri olan X ve Y biçimlerini tanımlayan noktaları gösterir ve X + Y'nin en dıştaki noktalarını ve ayrıca bazılarını da alırız .

Bu ek noktalar, X + Y'nin en dıştakileri tarafından "çevrelenmiştir", böylece yeni elde edilen dışbükey şeklinin tanımlanmasına katkıda bulunmazlar. Nokta kümesinin " dışbükey kabuğunu " tanımlamadıklarını söylüyoruz . Öyleyse yaptığımız şey, kökenin dışbükey gövde içinde olup olmadığını söyleyen son algoritmaya hazırlık olarak onlardan kurtulmamız.


X + Y'nin dışbükey gövdesi. "İç" köşelerini kaldırdık.

Biz bu nedenle almak

İlk, saf bir algoritma

boolean intersect(Shape X, Shape Y) {

  SetOfVertices minkowski = new SetOfVertices();
  for (Vertice x in X) {
    for (Vertice y in Y) {
      minkowski.addVertice(x-y);
    }
  }
  return contains(convexHull(minkowski), Vector2D(0,0));

}

Döngüler açık bir şekilde karmaşıklığa sahiptir O (mn) ki burada m ve n her şeklin köşeleridir. minkoswkiSeti içeren mn en fazla unsurları. convexHullAlgoritma bağlı olan bir karmaşıklığa sahiptir kullandığınız algoritma ve için amaç olabilir O (k günlüğüne (k)) k noktalarının kümesinin boyutu, yani bizim durumumuzda biz almak O (mn log (mn) ) . containsAlgoritma gerçekten sizin başlangıç şekilleri bağlıdır, böylece (2D) kenarları veya dışbükey kabuğun (3D) yüz sayısı ile doğrusal bir karmaşıklık var, ama daha büyük olmayacak O (mn) .

containsDışbükey şekiller için algoritma google size izin vereceğim , oldukça yaygın olanı. Vaktim varsa buraya koyabilirim.


Ama yaptığımız çarpışma tespiti, bunu çok daha iyi hale getirebiliriz

Başlangıçta zamanaşımı dt sırasında (resimlerinize bakarak söyleyebileceklerimden) iki gövdesi A ve B döndürmeden hareket ediyorduk . Let çağrısı v A ve v B ilgili hızları A ve B süresi bizim timestep sırasında sabit olan, dt . Aşağıdakileri alıyoruz:

ve, resimlerinizde işaret ettiğiniz gibi, bu gövdeler hareket ettikçe alanları (veya hacimleri, 3B) tararlar:

ve zaman aşımından sonra A ' ve B' olarak bitiyorlar.

Burada naif algoritmamızı uygulamak için sadece süpürülmüş hacimleri hesaplamamız gerekirdi. Ama bunu yapmıyoruz.

Referans çerçevesinde B , B (yaa!) Hareket etmez. Ve A , v A - v B'yi hesaplayarak elde ettiğiniz B'ye göre belirli bir hıza sahiptir (dönüştürmeyi yapabilirsiniz , A'nın referans çerçevesinde B'nin nispi hızını hesaplayabilirsiniz ).

Bağıl hareket

Soldan sağa: temel referans çerçevesindeki hızlar; bağıl hızlar; hesaplamalı göreceli hızlar.

İlgili olarak B kendi referans çerçevesinde hareketsiz olarak, Sadece sesi hesaplamak zorunda olduğunu bir o sırasında hareket ederken aracılığıyla temizleyicileri dt göreceli hız ile v A - v B .

Bu, Minkowski toplamı hesaplamasında kullanılacak köşe noktalarının sayısını azaltır (bazen büyük ölçüde).

Bir başka olası optimizasyon ise, gövdelerden birinin süpürdüğü hacmi hesapladığınız noktadadır. Diyelim ki, A. Diyelim ki bütün oluşturan köşeleri çevirmek zorunda değilsiniz. dış normal "yüz" süpürme yönü. Elbette, kareler için süpürülmüş alanlarınızı hesaplarken zaten bunu fark etmişsinizdir. Nokta ürününü, pozitif olması gereken süpürme yönü ile kullanarak normalin süpürme yönüne doğru olup olmadığını anlayabilirsiniz.

Kavşaklarla ilgili sorunuzla ilgisi olmayan son optimizasyon durumumuzda gerçekten yararlıdır. Bahsettiğimiz göreceli hızları ve sözde ayırma ekseni yöntemini kullanır. Elbette zaten biliyorsunuz.

Bildiğiniz varsayalım yarıçapları arasında A ve B kendi açısından kütle merkezleri bu gibi (söylemek kütle merkezinden ve ondan tepe uzak arasındaki mesafedir):

Bir çarpışma mümkün olması halinde ortaya çıkabilir Bunun sınırlayıcı daire A buluştuğu bu B . Burada görmeyeceğimizi ve bilgisayara aşağıdaki resimdeki C B ile I arasındaki mesafeyi hesaplamanın ve A ve B yarıçaplarının toplamından daha büyük olduğundan emin olmanın yolunu anlamanın yolunu görüyoruz . Daha büyükse, çarpışma olmaz. Daha küçükse, çarpışma.

Bu, uzun olan şekillerle çok iyi çalışmaz, ancak kareler veya bu tür başka şekiller söz konusu olduğunda, çarpışmayı dışlamak çok iyi bir sezgiseldir .

Bununla birlikte, B'ye uygulanan ayırma ekseni teorisi ve A tarafından kaydırılan hacim , çarpışmanın olup olmadığını size söyler. İlişkili algoritmanın karmaşıklığı, her dışbükey şeklin köşelerinin sayısının toplamı ile doğrusaldır, ancak çarpışmayı ele alma zamanı geldiğinde daha az büyülüdür.

Çarpışmaları algılamaya yardımcı olmak için kesişimleri kullanan yeni, daha iyi algoritmamız , ancak aslında bir çarpışmanın gerçekleşip gerçekleşmeyeceğini anlatmak için ayırma ekseni teoremi kadar iyi değil

boolean mayCollide(Body A, Body B) {

  Vector2D relativeVelocity = A.velocity - B.velocity;
  if (radiiHeuristic(A, B, relativeVelocity)) {
    return false; // there is a separating axis between them
  }

  Volume sweptA = sweptVolume(A, relativeVelocity);
  return contains(convexHull(minkowskiMinus(sweptA, B)), Vector2D(0,0));

}

boolean radiiHeuristic(A, B, relativeVelocity)) {
  // the code here
}

Volume convexHull(SetOfVertices s) {
  // the code here
}

boolean contains(Volume v, Vector2D p) {
  // the code here
}

SetOfVertices minkowskiMinus(Body X, Body Y) {

  SetOfVertices result = new SetOfVertices();
  for (Vertice x in X) {
    for (Vertice y in Y) {
      result.addVertice(x-y);
    }
  }
  return result;

}

2

'Altıgen'i kullanmak o kadar da faydalı değil. Eksen hizalı dikdörtgenler için tam çarpışmalar elde etmenin bir yolunu gösteren resim:

İki eksen hizalanmış dikdörtgen, eğer yalnızca X koordinatları üst üste, Y koordinatları da üst üste geldiğinde üst üste biner. (Bu, ayırma ekseni teoreminin özel bir durumu olarak görülebilir.) Yani, dikdörtgenleri X ve Y eksenlerine yansıtırsanız, sorunu iki çizgi kesişimine indirmiş olursunuz.

Bir eksen üzerindeki iki çizginin kesiştiği zaman aralığını hesaplayın (örn. Zamanda başlar (nesnelerin geçerli ayrılması / nesnelerin göreceli hızına yaklaşır)) ve diğer eksen için de aynısını yapın. Bu zaman aralıkları üst üste binerse, üst üste binme içindeki en erken zaman çarpışma zamanıdır.


3
Krokiyi unuttun.
MichaelHouse

2
@ Byte56 Hayır, demek istediğim bu bir algoritma taslağı değil hatta bir algoritma taslağı.
Kevin Reid

Ah anlıyorum. Benim hatam.
MichaelHouse

Bu aslında en kolay yöntemdir. Uygulamak için ilgili kodu ekledim.
Paşa

1

Çokgenlerin çarpışmasını bir dikdörtgenden daha fazla tarafla hesaplamanın kolay bir yolu olduğunu sanmıyorum. Çizgiler ve kareler gibi ilkel şekillere bölerdim:

function objectsWillCollide(object1,object2) {
    var lineA, lineB, lineC, lineD;
    //get projected paths of objects and store them in the 'line' variables

    var AC = lineCollision(lineA,lineC);
    var AD = lineCollision(lineA,lineD);
    var BC = lineCollision(lineB,lineC);
    var BD = lineCollision(lineB,lineD);
    var objectToObjectCollision = rectangleCollision(object1.getRectangle(), object2.getRectangle());

    return (AC || AD || BC || BD || objectToObjectCollision);
}

nesnelerin yollarının ve bitiş durumlarının gösterimi

Not Bunu her nesnenin başlangıç durumunu görmezden nasıl önceki hesaplama sırasında kontrol gerekirdi.


3
Bununla ilgili sorun, nesnelerin boyutları çok farklıysa, daha küçük nesnenin bir çarpışmayı tetiklemeden büyük nesnenin yolunun içinde hareket edebilmesidir.
API-Canavar

0

Ayrı Eksen Teoremi

Ayrı Eksen Teoremi, "İki dışbükey şeklin kesişmediği bir eksen bulabilirsek, o zaman iki şekil kesişmez" veya BT için daha pratiktir:

"İki dışbükey şekil, yalnızca tüm olası eksenlerde kesiştiğinde kesişir."

Eksen hizalı dikdörtgenler için tam olarak 2 olası eksen vardır: x ve y. Ancak teorem dikdörtgenlerle sınırlı değildir, sadece şekillerin kesiştiği diğer eksenleri ekleyerek herhangi bir dışbükey şekle uygulanabilir. Konuyla ilgili daha fazla bilgi için N geliştiricisinin bu öğreticiyi inceleyin: http://www.metanetsoftware.com/technique/tutorialA.html#section1

Uygulandığı gibi görünüyor:

axes = [... possible axes ...];
collision = true;
for every index i of axes
{
  range1[i] = shape1.getRangeOnAxis(axes[i]);
  range2[i] = shape2.getRangeOnAxis(axes[i]);
  rangeIntersection[i] = range1[i].intersectionWith(range2[i]);
  if(rangeIntersection[i].length() <= 0)
  {
    collision = false;
    break;
  }
}

Eksenler normalleştirilmiş vektörler olarak temsil edilebilir.

Aralık, 1 Boyutlu bir çizgidir. Başlangıç, öngörülen en küçük noktaya, bitecek en büyük noktaya ayarlanmalıdır.

Bunu "süpürülmüş" Dikdörtgene uygulama

Söz konusu altıgen, nesnenin AABB'sinin "süpürülmesi" ile üretilir. Süpürme, herhangi bir şekle tam olarak bir çarpışma ekseni ekler: hareket vektörü.

shape1 = sweep(originalShape1, movementVectorOfShape1);
shape2 = sweep(originalShape2, movementVectorOfShape2);

axes[0] = vector2f(1.0, 0.0); // X-Axis
axes[1] = vector2f(0.0, 1.0); // Y-Axis
axes[2] = movementVectorOfShape1.normalized();
axes[3] = movementVectorOfShape2.normalized();

Şimdiye kadar çok iyi, şimdi iki hexagon kesiştiği olup olmadığını kontrol edebiliriz. Ama daha da iyi olur.

Bu çözelti, herhangi bir dışbükey şekil (örneğin üçgenler) ve süpürülmüş dışbükey şekiller (örneğin, süpürülmüş sekizgenler) için çalışacaktır. Bununla birlikte, şekil ne kadar karmaşık olursa o kadar az etkili olacaktır.


Bonus: Sihrin olduğu yer.

Dediğim gibi sadece ek eksenler hareket vektörleridir. Hareket zamanla hız ile çarpılır, yani bir anlamda sadece uzay ekseni değiller, zaman-uzay eksenidir.

Bu, çarpışmanın gerçekleşebileceği zamanı bu iki eksenden türetebileceğimiz anlamına gelir. Bunun için hareket eksenindeki iki kesişme arasındaki kesişme noktasını bulmamız gerekir. Bunu yapabilmemiz için önce her iki aralığı da normalize etmemiz gerekir, böylece gerçekte bunları karşılaştırabiliriz.

shapeRange1 = originalShape1.getRangeOnAxis(axes[2]);
shapeRange2 = originalShape2.getRangeOnAxis(axes[3]);
// Project them on a scale from 0-1 so we can compare the time ranges
timeFrame1 = (rangeIntersection[2] - shapeRange1.center())/movementVectorOfShape1.project(axes[2]);
timeFrame2 = (rangeIntersection[3] - shapeRange2.center())/movementVectorOfShape2.project(axes[3]);
timeIntersection = timeFrame1.intersectionWith(timeFrame2);

Bu soruyu sorduğumda, bu yöntemle birkaç nadir yanlış pozitif olacağı konusunda uzlaşmayı kabul ettim. Ama yanılmışım, bu zamandaki kesişme noktasını kontrol ederek "gerçekte" çarpışmanın olup olmadığını test edebilir ve bu yanlış pozitifleri onunla çözebiliriz:

if(collision)
{
  [... timeIntersection = see above ...]
  if(timeIntersection.length() <= 0)
    collision = false;
  else
    collisionTime = timeIntersection.start; // 0: Start of the frame, 1: End of the frame
}

Kod örneklerinde herhangi bir hata olduğunu fark ederseniz, bana bildirin, henüz uygulamadım ve bu nedenle test edemedim.


1
Bir çözüm bulduğunuz için tebrikler! Ama daha önce de söylediğim gibi: sadece altıgenlerin kesiştiği bir çarpışma olacağı anlamına gelmez. Çarpışma zamanını istediğin kadar hesaplamak için yöntemini kullanabilirsin, çarpışma yoksa, çok kullanışlı olmaz. İkinci olarak, sadece 1 süpürülmüş hacmi hesaplamak ve SAT kullanırken hesaplamaları basitleştirmek için nispi hızları kullanabilirsiniz. Sonunda, sadece "kesişme zamanı" numaranızın nasıl çalıştığı ile ilgili kaba bir fikrim var, çünkü belki de endekslerinizi karıştırdınız, shapeRange1 == shapeRange2kodunuzda olduğu gibi görüyorsunuz , değil mi?
jrsala

@madshogo Şimdi daha mantıklı olmalı.
API-Canavar

Menzil normalleştirme olayının nasıl çalıştığını hala anlamadım, ama sanırım bir resme ihtiyacım var. Umarım sizin için işe yarar.
jrsala

-2

Kaydırılan alanların her ikisi de kapalı olduğu sürece (kenar çizgileri tarafından oluşturulan sınırlarda boşluk yoktur), aşağıdakiler işe yarar (çarpışma testlerinizi çizgi çizgisine ve nokta-doğrult / nokta-tri'ye düşürür):

  1. Kenarları temas ediyor mu? (çizgi-çizgi çarpışmaları) Bir süpürme alanının herhangi bir kenar çizgisinin, diğer süpürme alanının herhangi bir kenar çizgisiyle kesişip kesiştiğini kontrol edin. Her süpürülmüş alan 6 taraflıdır.

  2. Küçük olan büyük olanın içinde mi? (Eksen hizalanmış şekiller kullanın (nokta-doğrult ve nokta-tri)) Kaydırılan alanları yeniden hizalayın (çevirin), böylece daha büyük olanın eksen hizalı olmasını sağlayın ve daha küçük olanın iç olup olmadığını test edin (herhangi bir köşe noktasının olup olmadığını test ederek ( hepsi veya hiç olmamalıdır) eksen hizalı süpürme alanı içindedir). Bu, hex'inizi tris ve rect'lere ayırmaktır.

Hangi testi ilk önce yaptığınız her birinin olasılığına bağlıdır (ilk önce en çok yapılanları yapın).

Bir süpürülmüş sınırlayıcı daire (altıgen yerine kapsül) kullanmayı daha kolay bulabilirsiniz, çünkü eksenleri hizalı olduğunda iki yarım daireye ayırmak ve bir çizgiyi ayırmak daha kolaydır. .. çözümü çizmenize izin vereceğim


Dikdörtgenlerden biri gerçekten küçükse ve iki kenar çizgisi arasındaki boşlukta hareket ediyorsa işe yaramaz.
jrsala

@madshogo Cevabımı yeni ekledim. Şimdi tam bir çözüm olmalı.
akson

1
"Eksen hizalanmış şekilleri kullanın (nokta-doğrult ve nokta-tri)": Bir üçgeni veya bir "nokta üçgeni" (bu ne anlama gelirse) eksenlerle nasıl hizalarsınız? "böylece büyüğü eksen hizasında olacak": hangisinin diğerinden daha büyük olduğunu nasıl söyleyebilirsiniz? Alanlarını hesaplıyor musunuz? “Bu, hex'inizi tris ve rect'lere ayrıştırmakla yapılır.”: Hangi hex? İki tane. “(ya da senin için açıklamamı istiyorsan bu cevabı yenile)”: Ciddi misin ??
jrsala

“Bir üçgeni eksenlerle nasıl hizalarsınız?” C: Kaydırılan alanı oluşturan objenin yolunu hizalayın. Bir kenar seçin ve trig'i kullanın. "Hangisinin diğerinden daha büyük olduğunu nasıl söylersin?" C: Örneğin, çizginin çapraz olarak iki karşıt noktası (altıgenin ortası) arasındaki mesafeyi kullanın. "hangi altıgen?" A: Büyük olan.
akson
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.