Vektörler arasındaki açıları hesaplamanın sayısal olarak kararlı yolu


14

İki vektör arasındaki açı için klasik formülü uygularken:

α=arccosv1v2v1v2

çok küçük / akut açılar için hassasiyet kaybı olduğu ve sonucun doğru olmadığı bulunmuştur. Bu Yığın Taşması cevabında açıklandığı gibi , çözümlerden biri arktanjant kullanmaktır:

α=arctan2(v1×v2,v1v2)

Ve bu gerçekten daha iyi sonuçlar veriyor. Ancak, bunun \ pi / 2'ye çok yakın açılar için kötü sonuçlar vereceğini merak ediyorum π/2. Durum böyle mi? Öyleyse, bir ifdalın içindeki toleransı kontrol etmeden açıları doğru bir şekilde hesaplamak için herhangi bir formül var mı?


1
Bu, iki parametreli ters tanjant fonksiyonunun uygulanmasına bağlı olacaktır. Yavaş, kararlı sürümler, hassasiyeti korumak için x / y ve y / x ile çalışmak arasında koşullu olarak geçiş yaparken, hızlı olanlar sadece doğru çeyreğe yapışır ve bu nedenle tek parametreli sürümden daha kesin değildir.
origimbo

"Hassasiyet kaybı" tanımlamalısınız: doğru cevabın α ve bunun yerine \ alpha + \ Delta olduğunu varsayalım α+Δ. Eğer gerek Do Δα ya Δπ yeterlidir?
Stefano M

Bu durumda, doğru cevap ve aldım , her ikisi de . αα1081
astrojuanlu

Yanıtlar:


18

( Bu yaklaşımı daha önce test ettim ve doğru çalıştığını hatırlıyorum, ancak bu soru için özel olarak test etmedim. )

Anlayabildiğim kadarıyla, hem ve , neredeyse paralel / dikey olmaları durumunda felaket iptaline maruz kalabilirler - atan2, her iki giriş de kapalı olursa size iyi bir doğruluk sağlayamaz.v1×v2v1v2

Sorunu, kenar uzunluklarına sahip bir üçgenin açısını bularak yeniden biçimlendirerek başlayın. ,ve(bunların hepsi kayan nokta aritmetiğinde doğru olarak hesaplanır). Yan uzunluklarıyla belirtilen bir üçgenin alanını ve açısını ( ve arasında ) hesaplamanızı sağlayan Kahan ( Yanlış Hesaplanan Alan ve İğne Benzeri Üçgenin Açıları) nedeniyle Heron formülünün iyi bilinen bir çeşidi vardır , ve bunu sayısal olarak kararlı bir şekilde yapın. Bu alt problemin azaltılması da doğru olduğundan, bu yaklaşım keyfi girdiler için işe yaramalıdır.a=|v1|b=|v2|c=|v1v2|ab

Varsayarak (s.3 bakınız) kağıttan teklif , Buradaki tüm parantezler dikkatlice yerleştirilmiştir ve önemlidir; Kendinizi negatif bir sayının kare kökünü alırsanız, giriş tarafı uzunlukları bir üçgenin yan uzunlukları değildir.ab

μ={c(ab),if bc0,b(ac),if c>b0,invalid triangle,otherwise
angle=2arctan(((ab)+c)μ(a+(b+c))((ac)+b))

Kahan'ın makalesinde, diğer formüllerin başarısız olduğu değerlerin örnekleri de dahil olmak üzere, bunun nasıl çalıştığına dair bir açıklama var. Sizin ilk formülü olduğu sayfa 4.αC

Kahan'ın Heron'un formülünü önermemin ana nedeni, çok güzel bir ilkel yapmasıdır - potansiyel olarak zor düzlemsel geometri sorularının çoğu, rastgele bir üçgenin alanını / açısını bulmak için azaltılabilir, bu nedenle sorununuzu buna indirgeyebilirseniz, bunun için güzel ve kararlı bir formül ve kendi başınıza bir şey bulmanıza gerek yok.

Düzenle Stefano'nun yorumunu takiben , ( kod ) için göreceli hata grafiği . İki çizgi ve , için yatay eksen boyunca ilerleyen göreceli hatalardır . Görünüşe göre çalışıyor. v1=(1,0)v2=(cosθ,sinθ)θ=ϵθ=π/2ϵϵresim açıklamasını buraya girin


Bağlantı ve cevap için teşekkürler! Maalesef yazdığım ikinci formül makalede görünmüyor. Öte yandan, bu yöntem 2D olarak projeksiyon gerektirdiğinden biraz karmaşık olabilir.
astrojuanlu

2
@astrojuanlu Burada 2d'ye bir çıkıntı yok: iki 3B vektör ne olursa olsun, aralarında tek (düzlemsel) bir üçgen tanımlarlar - sadece yan uzunluklarını bilmeniz gerekir.
Kirill

Haklısın, yorumum bir anlam ifade etmiyor. Uzunluklar yerine koordinatlarda düşünüyordum. Tekrar teşekkürler!
astrojuanlu

2
@astrojuanlu Not etmek istediğim bir şey daha var: Görünüşe göre alan formülünün bir Üçgenin Alanını Hesaplama: Resmi bir Revisit , Sylvie Boldo , Flocq kullanarak doğru olduğuna dair resmi bir kanıt var .
Kirill

Mükemmel cevap, ama kayan nokta aritmetiğinde her zaman doğru bir şekilde hesaplayabileceğinize itiraz ediyorum . Aslında ise, bileşenlerinin hesaplanmasında yıkıcı iptaller gerçekleşir . cc<ϵmin(a,b)(v1v2)
Stefano M

7

Bu sorunun etkili cevabı, şaşırtıcı bir şekilde, Velvel Kahan'ın başka bir notunda :

α=2arctan(v1v1+v2v2,v1v1v2v2)

burada yatay eksenle tarafından yapılan açı olarak . (Bazı dillerde argümanların sırasını çevirmeniz gerekebilir.)arctan(x,y)(x,y)

( Burada Kahan formülünün bir Mathematica gösterimini yaptım .)


mi demek ? arctan2
astrojuanlu

1
Ben sadece iki argümanlı arktanjenti olarak resmediyorum , evet. FORTRAN gibi bir dilde, eşdeğer olur . arctan(x,y)ATAN2(Y, X)
JM
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.