ฉันจะคำนวณเวกเตอร์ปกติของส่วนของเส้นได้อย่างไร


177

สมมติว่าฉันมีส่วนของเส้นตรงเริ่มจาก (x1, y1) ถึง (x2, y2) ฉันจะคำนวณเวกเตอร์ปกติตั้งฉากกับเส้นได้อย่างไร

ฉันสามารถค้นหาสิ่งต่าง ๆ มากมายเกี่ยวกับการทำสิ่งนี้กับเครื่องบินในแบบ 3 มิติ แต่ไม่มีสิ่ง 2 มิติ

กรุณาไปที่เรื่องง่าย ๆ ทางคณิตศาสตร์ (เชื่อมโยงไปยังตัวอย่างการทำงานไดอะแกรมหรืออัลกอริทึมยินดีต้อนรับ) ฉันเป็นโปรแกรมเมอร์มากกว่าฉันเป็นนักคณิตศาสตร์;)


2
และถ้าคุณต้องการที่จะรู้ว่าที่ "คณิตศาสตร์" หลังนี้คุณสามารถดูคำตอบของฉันที่stackoverflow.com/a/7470098/189767 มันเป็นพื้นเดียวกัน แต่ซับซ้อนกว่า
Andreas

2
คำถามนี้เกี่ยวกับคณิตศาสตร์ไม่ใช่การเขียนโปรแกรม
Charlie

1
ฉันลงคะแนนเพื่อปิดคำถามนี้เป็นแบบปิดหัวข้อเนื่องจากเป็นเรื่องเกี่ยวกับคณิตศาสตร์ไม่ใช่การเขียนโปรแกรม
ปาง

คำตอบ:


237

ถ้าเรานิยาม dx = x2-x1 และ dy = y2-y1 ดังนั้นค่าปกติคือ (-dy, dx) และ (dy, -dx)

โปรดทราบว่าไม่จำเป็นต้องมีการหารดังนั้นคุณจึงไม่เสี่ยงต่อการหารด้วยศูนย์


14
มันค่อนข้างบอบบางและใช้เวลาสักครู่ในการตระหนักถึง normal.x = -dy และ normal.y = dx ฉันมีพวกเขาวิธีอื่น ๆ เพราะมันดูเหมือนพิมพ์ผิดกำหนดส่วน x เพื่อค่า Y ...
Piku

@OrenTrutner ฉันยังไม่เข้าใจสิ่งนี้ (x', y') = (-y, x)และ(x', y') = (y, -x)ดูเหมือนว่าจะถูกต้อง แต่ทำไมหนึ่งจะใช้dxและdyที่นี่ ยิ่งไปกว่านั้นขึ้นอยู่กับความลาดชันm1 * m2 = -1สำหรับเส้นมุมฉากเหตุนี้dy' = dx' * (-dx/dy)และdx' = dy' * (-dy/dx)สมการของคุณเป็นnormal.x = x' = -dyอย่างไร?
ตำนาน 2k

1
คุณช่วยอธิบายสั้น ๆ เพิ่มเติมเกี่ยวกับวิธีการที่เดลต้ามีบทบาทได้อย่างไร ฉันแน่ใจว่าฉันพลาดอะไรบางอย่างที่นี่
ตำนาน 2k

7
@ legends2k: เดลต้าเป็นเวกเตอร์แทนเจนต์ ปกติคือทิศทางตั้งฉากกับแทนเจนต์ การพลิกค่า x / y และลบค่ากลายเป็นชัดเจนถ้าคุณดูเมทริกซ์ 2D สำหรับการหมุน 90 องศา: en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
Geon

@geon: Aah! เข้าใจแล้วฉันสับสนเดลต้ากับความลาดชันในขณะที่เรขาคณิตเลียนแบบความแตกต่างระหว่างสองจุดคือเวกเตอร์, tanget ที่นี่ :)
legends2k

95

วิธีคิดอีกอย่างคือการคำนวณเวกเตอร์หน่วยสำหรับทิศทางที่กำหนดจากนั้นใช้การหมุนทวนเข็มนาฬิกา 90 องศาเพื่อให้ได้เวกเตอร์ปกติ

การแทนค่าเมทริกซ์ของการแปลง 2D ทั่วไปมีลักษณะดังนี้:

x' = x cos(t) - y sin(t)
y' = x sin(t) + y cos(t)

โดยที่ (x, y) เป็นส่วนประกอบของเวกเตอร์ดั้งเดิมและ (x ', y') เป็นส่วนประกอบที่ถูกแปลง

ถ้า t = 90 องศาดังนั้น cos (90) = 0 และ sin (90) = 1 การแทนที่และคูณมันจะให้:

x' = -y
y' = +x

ผลเช่นเดียวกับที่ระบุไว้ก่อนหน้านี้ แต่มีคำอธิบายเพิ่มเติมเล็กน้อยว่ามันมาจากไหน


2
ขอบคุณตันทำให้ฉันคิดว่ามันได้มาอย่างไร
ตำนาน 2k

1
แม้ว่าฉันจะรู้สูตรการหมุนก่อนหน้านี้สิ่งที่คลิกเข้าไปในหัวของฉันโดยคำตอบนี้คือมุมนั้นมีค่าคงที่ (+/- 90) ซึ่งทำให้มันง่ายต่อการปฏิเสธและการกลับรายการอย่างง่ายของ x และ y
ตำนาน 2k

@duffymo ผลลัพธ์มีความยาวหนึ่งรายการหรือไม่
Martin Meeser

ถ้าเวกเตอร์ถูกทำให้เป็นมาตรฐานก่อนการแปลงมันจะยังคงอยู่หลังจากนั้น คุณต้องทำให้เป็นมาตรฐานก่อนหรือหลังคุณทำการแปลงแบบหมุน
duffymo

11

คำถามนี้โพสต์เมื่อนานมาแล้ว แต่ฉันพบวิธีอื่นในการตอบคำถาม ดังนั้นฉันตัดสินใจแบ่งปันที่นี่
ประการแรกเราต้องรู้ว่า: หากเวกเตอร์สองตัวตั้งฉากตั้งฉากผลิตภัณฑ์ดอทจะเท่ากับศูนย์
เวกเตอร์ปกติ(x',y')จะตั้งฉากกับเส้นที่เชื่อมต่อกันและ(x1,y1) (x2,y2)บรรทัดนี้มีทิศทางหรือ(x2-x1,y2-y1) ดังนั้น,(dx,dy)

(x',y').(dx,dy) = 0
x'.dx + y'.dy = 0

มีคู่มากมาย (x ', y') ที่ตรงกับสมการข้างต้น แต่คู่ที่ดีที่สุดที่เสมอกันเป็นอย่างใดอย่างหนึ่ง(dy,-dx)หรือ(-dy,dx)


7
m1 = (y2 - y1) / (x2 - x1)

ถ้าตั้งฉากสองบรรทัด:

m1*m2 = -1

แล้วก็

m2 = -1 / m1 //if (m1 == 0, then your line should have an equation like x = b)

y = m2*x + b //b is offset of new perpendicular line.. 

b คือบางสิ่งถ้าคุณต้องการส่งผ่านจากจุดที่คุณกำหนด

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