หากคุณต้องการบางสิ่งบางอย่างที่ยังคงเป็นเส้นตรงในระยะทางใด ๆ (ไม่เหมือนdistance^2
) และยังปรากฏเป็นวงกลมอย่างชัดเจน (ไม่เหมือนกับ Chebyshev และระยะทางเหมือนแมนฮัตตันเพชร) คุณสามารถเฉลี่ยสองเทคนิคหลังเพื่อให้ได้ระยะทางประมาณรูปแปดเหลี่ยม:
dx = abs(x1 - x0)
dy = abs(y1 - y0)
dist = 0.5 * (dx + dy + max(dx, dy))
นี่คือการสร้างภาพ (โครงร่างของเส้นโค้ง) ของฟังก์ชันขอบคุณWolfram Alpha :
และนี่คือพล็อตของฟังก์ชั่นข้อผิดพลาดของมันเมื่อเปรียบเทียบกับระยะทางแบบยุคลิด (เรเดียน, จตุภาคแรกเท่านั้น):
อย่างที่คุณเห็นข้อผิดพลาดอยู่ในช่วงตั้งแต่ 0% ของแกนจนถึงประมาณ + 12% ในกลีบ ด้วยการปรับเปลี่ยนค่าสัมประสิทธิ์เล็กน้อยเราสามารถทำให้มันเป็น +/- 4%:
dist = 0.4 * (dx + dy) + 0.56 * max(dx, dy)
ปรับปรุง
เมื่อใช้ค่าสัมประสิทธิ์ข้างต้นความผิดพลาดสูงสุดจะอยู่ภายใน +/- 4% แต่ข้อผิดพลาดเฉลี่ยจะยังคงอยู่ที่ + 1.3% ปรับให้เหมาะสมสำหรับข้อผิดพลาดเฉลี่ยที่เป็นศูนย์คุณสามารถใช้:
dist = 0.394 * (dx + dy) + 0.554 * max(dx, dy)
ซึ่งให้ข้อผิดพลาดระหว่าง -5% ถึง + 3% และข้อผิดพลาดเฉลี่ยที่ + 0.043%
ขณะค้นหาชื่ออัลกอริทึมนี้บนเว็บฉันพบการประมาณแปดเหลี่ยมที่คล้ายกันนี้ :
dist = 1007/1024 * max(dx, dy) + 441/1024 * min(dx, dy)
โปรดทราบว่านี้จะเทียบเท่าหลัก (แม้ว่าเลขยกกำลังที่มีแตกต่างกัน - คนเหล่านี้ให้ความผิดพลาด -1.5% ถึง 7.5% แต่ก็สามารถจะนวดเพื่อ +/- 4%) max(dx, dy) + min(dx, dy) == dx + dy
เพราะ การใช้แบบฟอร์มนี้min
และการmax
โทรสามารถถูกแยกออกจากกันโดยชอบ:
if (dy > dx)
swap(dx, dy)
dist = 1007/1024 * dx + 441/1024 * dy
นี่จะเร็วกว่าเวอร์ชั่นของฉันหรือเปล่า ใครจะรู้ว่า ... ขึ้นอยู่กับคอมไพเลอร์และวิธีการปรับให้เหมาะสมสำหรับแพลตฟอร์มเป้าหมาย ฉันเดาว่ามันคงยากที่จะเห็นความแตกต่าง