2008-10-15 20 views
9

Nesnem var, yani (örneğin) 45 derecelik bir görüş alanı ve belirli bir sınırlama alanıyla belirli bir yöne bakıyor. Tüm ilk kontrolleri (Quadtree düğümü ve mesafe) yaptım, ama şimdi belirli bir nesnenin o ekran konisinin içinde olup olmadığını kontrol etmem gerekiyor, (Bu durumda, eğer görebiliyorsak o nesneyi takip etmeye karar vermemiz gerekir). Apart Direction + (FieldOfView/2) için Direction - (FieldOfView/2) her derece (şu anda bu yapıyorum ve korkunç) bir ışın döküm gelenBir oyun nesnesinin başka birini görüp göremeyeceğini nasıl kontrol edebilirim?

, bu görünürlük işaretini yapmanın en iyi yolu nedir?

cevap

9

Görüş yönünüzü (vektör olarak anlaşılır) ve baştan başlayıp nesneyle biten vektör arasındaki açıyı hesaplayın. Eğer FieldOfView/2'nin altına düşerse, nesneyi görebilirsiniz.

O açıdır:

arccos(scalarProduct(viewDirection, (object - you))/(norm(viewDirection)*norm(object - you))). 
+0

Teşekkürler, tam olarak aradığım şey. Bence bu, sahip olduğum şeye dayanarak bunu başarmanın en basit yolu. – AshtonKJ

2

Eğer 3D yapıyoruz ve bir konısidır olarak izleme aralığını tanımlayabilirsiniz, o zaman bu Frustrum Culling tekniğe benzer bir şey kullanabilirsiniz.

3

Görüntüleyicinin başlık vektörü ile vektörü görüntüleyiciden hedefe doğru alın. Bu açı, (FieldOfView/2) değerinden daha azsa, hedef görüntüleyicinin görüş alanındadır.

Vektörleriniz 2d veya 3d ise, bu aynı şekilde çalışır. (3B'de, koninin yerine bir görünüm boşluğuna sahipseniz, o zaman açıları iki bileşene ayırmanız gerekir.) Sadece iki vektör arasındaki açıyı bulmanız gerekir.

Tek bir noktadan daha büyük olan hedefleri test etmek isterseniz, sınırlama kutusunun köşeleri gibi her hedef için birden çok noktaya ihtiyacınız olacaktır. Bu noktalardan herhangi birine görüntüleyici vektörü görüş alanının içinde bir açı veriyorsa, kutunun o köşesi görünür.

10

Video oyun endüstrisinde çalıştım ve her çerçeve arccos gibi trig işlevlerinin idealin altında olduğunu söyleyebilirim. Bunun yerine, koni açısının kosinüsünü precompute: Bir nokta nokta koni ürünü ve o karşılaştırarak bu koni içindeki düşerse

float cos_angle = cos(PI/4); // 45 degrees, for example 

Sonra, her kare hızla kontrol edebilirsiniz.

vector test_point_vector = normalize(test_point_loc - cone_origin); 
float dot_product = dot(normalized_cone_vector, text_point_vector); 
bool inside_code = dot_product > cos_angle; 

hiçbir trigonometri fonksiyonları, sadece bazı çarpma, bölme ve ekleme vardır. Çoğu oyun motorunun vektörler için optimize edilmiş bir normalize() işlevi vardır.

Bunun nedeni bu denklemin çalışır:

A · B = |A| * |B| * cos(Θ) 

Eğer vektörleri (A -> An) normalleştirmek ise denklem basitleştirilmiş:

An · Bn = cos(Θ) 
+0

Bunun için teşekkürler. Çerçeve başına trig fonksiyonlarının miktarını sınırlama fikrini seviyorum. Kesinlikle bunu denemeye çalışacağım (Ne yazık ki, sadece sınavlar bittiğinde). – AshtonKJ

+0

Bu cevabı seviyorum. Bir not olarak, bu çözüm sadece bir "frustum check" yapacak ve duvarlar ve diğer nesneler tarafından tıkanıklık ile uğraşmaz. –

1

İyi cevaplar zaten ama sadece istedim Wolfire bloguna bir link verdiler, kısa bir süre önce "görüş alanı" denklemini bir örnek olarak alan bir cebir dizisi başlattılar. Go read it, iyi yazılmış ve kolay.

İlgili konular