อะไรคือความแตกต่างระหว่าง atan และ atan2 ใน C ++?


คำตอบ:



322

จากคณิตศาสตร์ของโรงเรียนเรารู้ว่าแทนเจนต์มีความหมาย

tan(α) = sin(α) / cos(α)

และเราแยกความแตกต่างระหว่างควอดเรนท์สี่มุมตามมุมที่เราให้กับฟังก์ชัน เครื่องหมายของsin, cosและtanมีความสัมพันธ์ต่อไป (ที่เราละเลยหลายที่แน่นอนของπ/2):

  Quadrant    Angle              sin   cos   tan
-------------------------------------------------
  I           0    < α < π/2      +     +     +
  II          π/2  < α < π        +     -     -
  III         π    < α < 3π/2     -     -     +
  IV          3π/2 < α < 2π       -     +     -

เนื่องจากค่าของtan(α)เป็นบวกเราไม่สามารถแยกแยะได้ว่ามุมนั้นมาจากจตุภาคที่หนึ่งหรือสามและถ้ามันเป็นลบมันอาจมาจากจตุภาคที่สองหรือสี่ ดังนั้นโดยการประชุมatan()ส่งคืนมุมจากจตุภาคที่หนึ่งหรือสี่ (เช่น-π/2 <= atan() <= π/2) โดยไม่คำนึงถึงอินพุตดั้งเดิมไปยังแทนเจนต์

เพื่อให้ได้ข้อมูลที่ครบถ้วนกลับมาเราจะต้องไม่ใช้ผลลัพธ์ของการหารsin(α) / cos(α)แต่เราต้องดูค่าของไซน์และโคไซน์แยกกัน และนี่คือสิ่งที่atan2()ทำ มันใช้ทั้งสองsin(α)และcos(α)และแก้ไขทั้งสี่ภาคโดยการเพิ่มπผลของatan()เมื่อใดก็ตามที่โคไซน์เป็นลบ

หมายเหตุ:atan2(y, x)ฟังก์ชั่นจริงจะใช้เวลาyและxการโต้แย้งซึ่งเป็นประมาณการของเวกเตอร์ที่มีความยาวที่vและมุมαบน y- และแกน x คือ

y = v * sin(α)
x = v * cos(α)

ซึ่งให้ความสัมพันธ์

y/x = tan(α)

สรุป: atan(y/x)มีการระงับข้อมูลบางอย่างและสามารถสันนิษฐานได้ว่าข้อมูลมาจาก quadrants I หรือ IV ในทางตรงกันข้ามatan2(y,x)ได้รับข้อมูลทั้งหมดและสามารถแก้ไขมุมที่ถูกต้อง


3
หนึ่งรายละเอียดเล็ก ๆ ช่วง-π/2 <= atan() <= π/2จริง ๆ แล้วรวมหนึ่งจุด ( pi/2) จาก Quadrant II
Z boson

28

อีกสิ่งที่จะกล่าวถึงคือatan2มีเสถียรภาพมากขึ้นเมื่อคำนวณ tangents โดยใช้นิพจน์เช่นatan(y / x)และxเป็น 0 หรือใกล้กับ 0


น่าสนใจคุณมีแหล่งข้อมูลสำหรับสิ่งนี้หรือไม่? นี่เป็นเรื่องจริงโดยทั่วไปหรือเพียงแค่สำหรับ C ++?
เจอราร์ด

26

ค่าจริงอยู่ในรูปเรเดียน แต่เมื่อต้องการตีความค่าเป็นองศามันจะเป็น:

  • atan = ให้ค่ามุมระหว่าง -90 ถึง 90
  • atan2 = ให้ค่ามุมระหว่าง -180 ถึง 180

สำหรับงานของฉันที่เกี่ยวข้องกับการคำนวณมุมต่าง ๆ เช่นหัวเรื่องและทิศทางในการนำทางatan2ในกรณีส่วนใหญ่ทำงาน


12

atan (x) ส่งคืนค่าหลักของส่วนโค้งแทนเจนต์ของ x ซึ่งแสดงเป็นเรเดียน

atan2 (y, x) ส่งคืนค่าหลักของส่วนโค้งแทนเจนต์ของ y / x ซึ่งแสดงเป็นเรเดียน

ขอให้สังเกตว่าเนื่องจากความกำกวมของสัญญาณฟังก์ชันไม่สามารถตรวจสอบได้อย่างแน่นอนว่ามุมใดของจตุภาคที่ตกตามค่าสัมผัสแทน (atan alone) คุณสามารถใช้ atan2 ได้หากคุณต้องการหา Quadrant


3
atan2 (x, y) -> atan2 (y, x)
yesraaj

ช่วงของค่าหลักการคือ(-pi,pi]แต่ atan2 มีช่วง[-pi,pi]จึงรวมถึงหนึ่งมูลค่าเพิ่ม-piจากสาขาอื่นเนื่องจากการสำหรับatan2(-0.0,x) x<0
Z boson

4

ฉันเดาว่าคำถามหลักพยายามที่จะคิดออก: "เมื่อใดฉันจึงควรใช้อย่างใดอย่างหนึ่ง" หรือ "ที่ฉันควรใช้" หรือ "ฉันใช้อันที่ถูกต้อง" หรือไม่?

ฉันเดาว่าจุดสำคัญคือ atan เท่านั้นมีวัตถุประสงค์เพื่อป้อนค่าบวกในเส้นโค้งทิศทางขึ้นไปทางขวาเช่นสำหรับเวกเตอร์ระยะทาง Cero อยู่ที่ด้านล่างซ้ายเสมอและหัวสามารถขึ้นและลงได้ช้าหรือเร็วกว่า atan ไม่ส่งคืนจำนวนลบดังนั้นคุณไม่สามารถติดตามสิ่งต่าง ๆ ใน 4 ทิศทางบนหน้าจอเพียงแค่เพิ่ม / ลบผลลัพธ์

atan2 มีจุดประสงค์เพื่อให้จุดเริ่มต้นอยู่ตรงกลางและสิ่งต่าง ๆ สามารถถอยหลังหรือลงได้ นั่นคือสิ่งที่คุณจะใช้ในการแสดงหน้าจอเพราะมันไม่สำคัญว่าคุณต้องการให้เส้นโค้งไปทางใด ดังนั้น atan2 สามารถให้ตัวเลขติดลบได้เพราะซีโร่มันอยู่ตรงกลางและผลลัพธ์คือสิ่งที่คุณสามารถใช้ติดตามสิ่งต่าง ๆ ใน 4 ทิศทาง


2

ด้วย atan2 คุณสามารถกำหนดวอดตามที่ระบุไว้ที่นี่

คุณสามารถใช้ atan2 ได้หากคุณต้องการหา Quadrant


2

พิจารณาสามเหลี่ยมมุมฉาก เราใส่เครื่องหมายด้านตรงข้ามมุมฉาก r, ด้านแนวนอน y และด้านแนวตั้ง x มุมที่น่าสนใจαคือมุมระหว่าง x และ r

C ++ atan2(y, x)จะให้ค่ามุมαเป็นเรเดียน atanจะใช้ถ้าเรารู้หรือสนใจใน y / x ไม่ใช่ y และ x ทีละคน ดังนั้นถ้า p = Y / X atan(p)แล้วที่จะได้รับαเราต้องการใช้

คุณไม่สามารถใช้atan2เพื่อกำหนด Quadrant คุณสามารถใช้atan2เฉพาะเมื่อคุณทราบแล้วว่า Quadrant ของคุณใน! โดยเฉพาะค่าบวก x และ y หมายถึงจตุภาคแรก, ค่าบวก y และค่าลบ x, ค่าที่สองและอื่น ๆ atanหรือatan2ตัวเองเพียงแค่คืนค่าจำนวนบวกหรือลบไม่มีอะไรเพิ่มเติม


4
หากสิ่งที่คุณมีคือคุณยังสามารถใช้p=y/x atan2(p,1)
Mark Ransom

0

Mehrwolf ด้านล่างถูกต้อง แต่นี่คือฮิวริสติกซึ่งอาจช่วยได้:

หากคุณกำลังทำงานในระบบพิกัดสองมิติซึ่งเป็นกรณีของการเขียนโปรแกรมแทนเจนต์ผกผันคุณควรใช้ atan2 อย่างแน่นอน มันจะให้มุม 2 ไพเต็มและจัดการศูนย์ในพิกัด x สำหรับคุณ

อีกวิธีในการพูดแบบนี้คือ atan (y / x) นั้นผิดเสมอ ใช้ atan ก็ต่อเมื่อไม่สามารถคิดว่าอาร์กิวเมนต์เป็น y / x


0

atan2(y,x)โดยทั่วไปจะใช้หากคุณต้องการแปลงพิกัดคาร์ทีเซียนเป็นพิกัดเชิงขั้ว มันจะให้มุมในขณะที่sqrt(x*x+y*y)หรือถ้ามีhypot(y,x)จะให้ขนาด

atan(x)เป็นเพียงการผกผันของผิวสีแทน ในกรณีที่น่ารำคาญคุณต้องใช้atan(y/x)เพราะระบบของคุณไม่ได้ให้atan2คุณจะต้องทำการตรวจสอบเพิ่มเติมสำหรับสัญญาณของxและyและx=0เพื่อให้ได้มุมที่ถูกต้อง

หมายเหตุ: atan2(y,x)ถูกกำหนดสำหรับค่าจริงทั้งหมดของyและxยกเว้นกรณีและปัญหาเมื่ออาร์กิวเมนต์ทั้งสองเป็นศูนย์


0

ใน atan2 ผลลัพธ์คือ: -pi< atan2(y,x)< pi
และ Atan ผลลัพธ์คือ: -pi/2< atan(y/x)< pi/2 // มันยาได้พิจารณาไตรมาสที่
หากคุณต้องการที่จะได้รับการปฐมนิเทศระหว่าง0และ2*pi(เช่นคณิตศาสตร์มัธยม) เราจำเป็นต้องใช้ atan2 และสำหรับค่าลบเพิ่ม2*piเพื่อให้ได้ผลสุดท้ายระหว่างและ0 นี่คือซอร์สโค้ด Java เพื่ออธิบายอย่างชัดเจน:2*pi

System.out.println(Math.atan2(1,1)); //pi/4 in the 1st quarter
System.out.println(Math.atan2(1,-1)); //(pi/4)+(pi/2)=3*(pi/4) in the 2nd quarter

System.out.println(Math.atan2(-1,-1 ));//-3*(pi/4) and it is less than 0.
System.out.println(Math.atan2(-1,-1)+2*Math.PI); //5(pi/4) in the 3rd quarter

System.out.println(Math.atan2(-1,1 ));//-pi/4 and it is less than 0.
System.out.println(Math.atan2(-1,1)+2*Math.PI); //7*(pi/4) in the 4th quarter

System.out.println(Math.atan(1 ));//pi/4
System.out.println(Math.atan(-1 ));//-pi/4
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.