วิธีการคำนวณมุมที่มีเสถียรภาพของตัวเลขระหว่างเวกเตอร์


14

เมื่อใช้สูตรคลาสสิกสำหรับมุมระหว่างสองเวกเตอร์:

α=arccosv1v2v1v2

หนึ่งพบว่าสำหรับมุมเล็ก / เฉียบพลันมากมีการสูญเสียความแม่นยำและผลลัพธ์ไม่ถูกต้อง ดังที่อธิบายไว้ในคำตอบของ Stack Overflow คำตอบเดียวคือใช้อาร์กแทนเจนต์แทน:

α=arctan2(v1×v2,v1v2)

และสิ่งนี้ย่อมให้ผลลัพธ์ที่ดีกว่า อย่างไรก็ตามฉันสงสัยว่าสิ่งนี้จะให้ผลที่ไม่ดีกับมุมที่อยู่ใกล้กับπ/2หรือไม่ เป็นอย่างนั้นเหรอ? ถ้าเป็นเช่นนั้นมีสูตรใดที่จะคำนวณมุมอย่างแม่นยำโดยไม่ตรวจสอบความอดทนภายในifสาขาหรือไม่?


1
สิ่งนี้จะขึ้นอยู่กับการใช้งานฟังก์ชั่นแทนเจนต์ของพารามิเตอร์สองตัว รุ่นที่ช้าและเสถียรจะสลับอย่างมีเงื่อนไขระหว่างการทำงานกับ x / y และ y / x เพื่อรักษาความแม่นยำในขณะที่รุ่นที่รวดเร็วเพียงติดสิ่งต่าง ๆ ใน Quadrant ที่เหมาะสมและดังนั้นจึงไม่แม่นยำกว่ารุ่นพารามิเตอร์เดียว
origimbo

คุณควรกำหนด "การสูญเสียของความแม่นยำ": คิดว่าคำตอบที่ถูกต้องคือαและคุณได้รับแทนα+Δ\ คุณต้องการΔαหรือΔπเพียงพอหรือไม่
Stefano M

ในกรณีนี้คำตอบที่ถูกคือและฉันได้ทั้ง1 αα1081
astrojuanlu

คำตอบ:


18

( ฉันได้ทดสอบวิธีการนี้มาก่อนและฉันจำได้ว่าทำงานได้อย่างถูกต้อง แต่ฉันไม่ได้ทดสอบวิธีนี้โดยเฉพาะสำหรับคำถามนี้ )

เท่าที่ฉันจะบอกได้ทั้ง และสามารถทนทุกข์ทรมานจากการยกเลิกหายนะหากพวกเขาเกือบขนาน / ตั้งฉากกัน - atan2 ไม่สามารถให้ความแม่นยำที่ดีถ้าอินพุตปิดv1×v2v1v2

เริ่มต้นโดยปรับโครงสร้างปัญหาใหม่เพื่อหามุมของสามเหลี่ยมที่มีความยาวด้าน,และ(สิ่งเหล่านี้คำนวณได้อย่างแม่นยำในการคำนวณเลขทศนิยม) มีสูตรที่เป็นที่รู้จักกันดีของนกกระสาเนื่องจาก Kahan (การคำนวณพื้นที่และมุมของสามเหลี่ยมคล้ายเข็ม ) ซึ่งช่วยให้คุณคำนวณพื้นที่และมุม (ระหว่างและ ) ของรูปสามเหลี่ยมที่ระบุโดยความยาวด้าน และทำอย่างเสถียรเชิงตัวเลข เนื่องจากการลดลงของปัญหาย่อยนี้มีความถูกต้องเช่นกันวิธีการนี้ควรใช้กับอินพุตที่กำหนดเองa=|v1|b=|v2|c=|v1v2|ab

การอ้างถึงจากกระดาษนั้น (ดูหน้า 3) โดยสมมติว่า , วงเล็บทั้งหมดที่นี่ถูกวางไว้อย่างระมัดระวังและพวกมันสำคัญ; หากคุณพบว่าตัวเองกำลังหาสแควร์รูทของจำนวนลบความยาวด้านอินพุตนั้นไม่ใช่ความยาวด้านของสามเหลี่ยมab

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

มีคำอธิบายวิธีการทำงานรวมถึงตัวอย่างของค่าที่สูตรอื่น ๆ ล้มเหลวในกระดาษของ Kahan สูตรแรกของคุณสำหรับคือในหน้า 4αC

เหตุผลหลักที่ฉันแนะนำสูตรของ Kahan Heron ก็คือเพราะมันเป็นสูตรดั้งเดิมที่ดีมาก - คำถามเรขาคณิตเชิงระนาบจำนวนมากอาจลดลงเพื่อหาพื้นที่ / มุมของสามเหลี่ยมโดยพลการดังนั้นถ้าคุณสามารถลดปัญหาของคุณได้นั่นคือ เป็นสูตรที่เสถียรดีและไม่จำเป็นต้องคิดอะไรขึ้นมาเอง

แก้ไขความคิดเห็นของสเตฟาโนฉันทำพล็อตข้อผิดพลาดแบบสัมพัทธ์สำหรับ , ( รหัส ) สองบรรทัดคือข้อผิดพลาดสัมพัทธ์สำหรับและ ,จะไปตามแกนนอน ดูเหมือนว่ามันใช้งานได้ v1=(1,0)v2=(cosθ,sinθ)θ=ϵθ=π/2ϵϵป้อนคำอธิบายรูปภาพที่นี่


ขอบคุณสำหรับลิงค์และคำตอบ! น่าเสียดายที่สูตรที่สองที่ฉันเขียนไม่ปรากฏในบทความ ในทางกลับกันวิธีนี้อาจมีความซับซ้อนเล็กน้อยเนื่องจากต้องใช้การฉายภาพในแบบ 2D
astrojuanlu

2
@astrojuanlu ไม่มีการฉายเป็น 2d ตรงนี้: ไม่ว่าเวกเตอร์ 3 มิติสองตัวใดก็ตามพวกมันนิยามสามเหลี่ยม (ระนาบ) เดี่ยวระหว่างพวกมัน - คุณแค่ต้องรู้ความยาวข้างของมัน
คิริลล์

คุณพูดถูกแล้วความคิดเห็นของฉันไม่สมเหตุสมผล ฉันคิดในพิกัดแทนความยาว ขอบคุณอีกครั้ง!
astrojuanlu

2
@astrojuanlu อีกสิ่งหนึ่งที่ฉันต้องการทราบ: ดูเหมือนว่ามีการพิสูจน์อย่างเป็นทางการว่าสูตรพื้นที่มีความถูกต้องในวิธีการคำนวณพื้นที่ของรูปสามเหลี่ยม: Revisit อย่างเป็นทางการ Sylvie Boldoใช้ Flocq
คิริลล์

คำตอบที่ดี แต่ฉันโต้แย้งว่าคุณสามารถคำนวณในเลขทศนิยมได้อย่างถูกต้อง ในความเป็นจริงถ้าการยกเลิกการจองแล้วภัยพิบัติที่เกิดขึ้นในการคำนวณองค์ประกอบของ_2) cc<ϵmin(a,b)(v1v2)
Stefano M

7

คำตอบที่มีประสิทธิภาพสำหรับคำถามนี้คือไม่น่าประหลาดใจเกินไปในบันทึกอื่นโดย Velvel Kahan :

α=2arctan(v1v1+v2v2,v1v1v2v2)

โดยที่ฉันใช้เป็นมุมที่สร้างโดยกับแกนนอน (คุณอาจต้องเรียงลำดับอาร์กิวเมนต์ในบางภาษา)arctan(x,y)(x,y)

(ฉันให้การสาธิตMathematicaสูตร Kahan ที่นี่ )


คุณหมายถึง ? arctan2
astrojuanlu

1
ฉันคุ้นเคยกับการวาดอาร์กแทนเจนต์สองอาร์กิวเมนต์ในชื่อใช่ ในภาษาเช่น FORTRAN เทียบเท่าจะเป็น arctan(x,y)ATAN2(Y, X)
JM
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.