ฉันจะบอกได้อย่างไรว่าวัตถุกำลังเคลื่อนไหว CW หรือ CCW รอบ ๆ เส้นทางที่เชื่อมต่อหรือไม่


19

ให้บอกว่าเรามีรูปร่างขรุขระ:

shape0

และสิ่งมีชีวิตสองอย่างที่เคลื่อนไหวตามโครงร่าง

จากนั้นเราปรับรูปร่างให้เรียบโดยการดึงมุมออกมา

เราได้รับสิ่งนี้:

เรียบ

ตอนนี้เป็นเรื่องง่ายที่จะเห็นว่า Orange กำลังเคลื่อนไหว CW และ CCW สีเขียว ฉันจะบอกได้อย่างไรว่าทิศทางใดที่พวกเขาเคลื่อนไหวโดยไม่ทำให้รูปร่างเรียบ

ภาพใหม่

ป้อนคำอธิบายรูปภาพที่นี่


นี่คือ 2 เซ็นต์ของฉัน: i.imgur.com/zrBdw.png
Kendall Frey

คำตอบ:


27

ลากเส้นไปที่ระยะอนันต์และนับจำนวนครั้งที่คุณข้ามรูปร่าง (หรือคี่) ไม่นับส่วนที่สัตว์นั้นอยู่ จากนั้นตรวจสอบว่าสิ่งมีชีวิตกำลังจะไปทางซ้ายหรือทางขวาของบรรทัดนั้น

ตัวอย่าง

ในตัวอย่างนี้เราข้ามรูปร่างสองครั้ง (เท่ากัน) และเราไปทางซ้าย ผลลัพธ์จะมาจากตารางนี้ทันที:

   # Crosses | even  | odd
  Direction  |       |
-------------+-------+------
    left     | CCW   |  CW
    right    |  CW   | CCW

ใน pseudocode:

x, y = position of creature
vx, vy = direction of creature movement
crossings = 0
for each x1, y1, x2, y2 in shape segments:
    if (x1 < x and x <= x2) or (x2 < x and x <= x1):
        if y - y1 > (x - x1) * (y2 - y1) / (x2 - x1):
            ++crossings
if (crossings & 1) == (vx < 0):
    return CW
else
    return CCW

คุณรวมสิ่งมีชีวิตที่กำลังดำเนินการอยู่หรือไม่?
Ali1S232

@Gajoo: ไม่ดังนั้น> แทน> = ที่บรรทัด 6 ฉันจะเพิ่มบันทึกเกี่ยวกับสิ่งนี้ แต่โปรดทราบว่าคุณสามารถรวมบรรทัดและเพียงย้อนกลับเนื้อหาตาราง
sam hocevar

1
ฉันต้องสลับไปมาระหว่างการให้คำตอบตามวิธีนี้กับคำตอบที่ฉันให้ ฉันดีใจที่เรามีทั้งสองวิธีที่นี่ อันนี้เป็นแนวคิดที่ง่ายและสง่างามมาก แต่ต้องมีการทดสอบการตัดกันของส่วนของเส้นตรงซึ่งอาจเป็นเรื่องยากที่จะทำให้มีประสิทธิภาพ
เทรเวอร์พาวเวลล์

@TrevorPowell True การค้นหาขอบที่ไกลที่สุดอาจทำให้สับสน ฉันตรวจสอบก่อนตามจุดสุดยอดที่อยู่ไกลที่สุดของขอบจากนั้นฉันวาดเส้นจากกึ่งกลางของรูปร่างและผ่านจุดกึ่งกลางของขอบทั้งสอง อินฟินิตี้หลังจากข้ามหนึ่งในขอบเหล่านี้ มันใช้ได้ดี
wolfdawn

5

ขึ้นอยู่กับข้อมูลที่คุณมีจากโครงสร้างข้อมูลรูปร่างของคุณ แต่สิ่งมีชีวิตที่เคลื่อนไหว CW ไปตามโครงร่างของรูปร่างจะมีด้านในของรูปร่างอยู่ทางขวาเสมอและ CCW ที่เคลื่อนไหวของสัตว์จะมีรูปร่างด้านใน มันซ้าย


ทางออกที่ง่ายกว่ามากและเป็นความคิดแรกของฉัน
Amplify91

คุณรู้ได้อย่างไรว่าทิศทางใดที่อยู่ภายในรูปร่าง ฉันหมายถึงการเคลื่อนที่ไปตามขอบด้านในของรูปร่างนั้นคือด้านซ้ายหรือด้านขวาของคุณ คุณจะรู้ได้อย่างไรว่ามันคืออะไร?
Ali1S232

ทางออกที่หรูหรามาก แต่ไม่เป็นความจริงโดยทั่วไป ลองนึกภาพโดนัทที่แบนบนโต๊ะเพื่อทำให้เป็นรูปทรงสองมิติ คุณสามารถเดินไปตามขอบของรูปร่างนี้เก็บภายในของรูปร่างด้านซ้ายของคุณและทำตามเข็มนาฬิกาหรือตักทวนเข็มนาฬิกาขึ้นอยู่กับว่าคุณเริ่มต้น
Marcks Thomas

4
  1. คำนวณจุดกึ่งกลางของรูปร่างของคุณ
  2. เลือกขอบที่ห่างไกลที่สุดของรูปร่างจากกึ่งกลาง
    • (การเลือกขอบที่ห่างไกลที่สุดทำให้แน่ใจได้ว่าคุณไม่ได้เริ่มต้นจากส่วนกลับเว้าของรูปร่างซึ่งจะส่งผลให้ได้การกำหนดตามเข็มนาฬิกา / ทวนเข็มนาฬิกาย้อนกลับสำหรับรูปร่างทั้งหมด)
  3. กำหนดทิศทางตามแนวขอบนั้นตามเข็มนาฬิกา
    • (การใช้งานอย่างง่ายของสิ่งนี้จะเกี่ยวข้องกับการเปรียบเทียบมุมจากศูนย์กลางของรูปร่างกับปลายแต่ละด้านของขอบที่เลือกสัญลักษณ์ของความแตกต่างระหว่างมุมจะบอกตามเข็มนาฬิกาของคุณกับทวนเข็มนาฬิกา)
  4. วนซ้ำของขอบทั้งหมดของรูปร่างเริ่มต้นจากขอบที่คุณเลือกในขั้นตอนที่ 2 สร้างรายการขอบ สำหรับแต่ละขอบให้เก็บสองจุดยอดตามลำดับตามเข็มนาฬิกา
    • (หากรูปร่างของคุณไม่เปลี่ยนแปลงเมื่อเวลาผ่านไปคุณสามารถเก็บรายการขอบนี้ไว้เพื่อใช้ในภายหลังดังนั้นคุณไม่ต้องทำสี่ขั้นตอนแรกทุกเฟรม)
    • (คุณอาจมีรายการขอบอยู่แล้วหากเป็นเช่นนั้นคุณสามารถเก็บลำดับจุดสุดยอดตามเข็มนาฬิกานี้ไว้ในรายการเดียวกันได้)
  5. ในการตรวจสอบว่าเอนทิตีเคลื่อนตามเข็มนาฬิกาหรือทวนเข็มนาฬิกา:
    • กำหนดว่าเอนทิตีขอบใดที่กำลังเคลื่อนไป
    • ทำผลิตภัณฑ์ดอทของทิศทางการเคลื่อนที่ของเอนทิตีกับเวกเตอร์จากจุดยอดตามจุดเริ่มต้น -> สิ้นสุดของทวนเข็มนาฬิกาซึ่งคุณได้กำหนดกลับมาในขั้นตอนที่ 4
    • หากผลลัพธ์ของผลิตภัณฑ์ดอทเป็นค่าที่มากกว่าศูนย์เอนทิตีจะเคลื่อนที่ตามเข็มนาฬิกา น้อยกว่าศูนย์หมายถึงทวนเข็มนาฬิกา

คำตอบที่ฉลาดมาก
wolfdawn

ฉันมีคำถามเล็กน้อย? สมมติว่าจุดยอดในรูปร่างของเขานั้นมีหมายเลขเริ่มต้นจากจุดที่เหลือมากที่สุด CWW ตามคำตอบของคุณฉันจะบอกได้อย่างไรว่าการย้ายจาก 6-> 7 หรือ 9-> 10 (ขึ้นอยู่กับศูนย์) กำลังเคลื่อนที่ตามเข็มนาฬิกา?
Ali1S232

คุณเริ่มต้นด้วยขอบที่อยู่ไกลที่สุดและหาวิธีตามเข็มนาฬิกาบนขอบนั้น สมมุติว่า edge A ตามเข็มนาฬิกาจากจุดยอด 'a' ถึง 'b' ถ้าเราย้ายไปที่ขอบ B (ซึ่งมีจุดยอด 'b' และ 'c') เรารู้ว่า B นั้นตามเข็มนาฬิกาจาก 'b' ถึง 'c' ในทำนองเดียวกันขอบ C จะเป็นตามเข็มนาฬิกาจาก 'c' ถึง 'd' เมื่อเราทราบทิศทางตามเข็มนาฬิกาที่ถูกต้องจากขอบหนึ่ง (ขั้นตอนที่ 1-3) โดยดำเนินการในทิศทางตามเข็มนาฬิการอบขอบของรูปร่างเราสามารถอนุมานทิศทาง 'ตามเข็มนาฬิกา' ที่ถูกต้องสำหรับทุกขอบโดยไม่ต้องดูที่ขอบของมัน เว้าจึงตกลง
เทรเวอร์พาวเวลล์

คุณจะบอกได้อย่างไรว่าขอบ A เป็นตามเข็มนาฬิกาจาก 'a' ถึง 'b' หรือถ้ามันตามเข็มนาฬิกาจาก 'b' ถึง 'a' ฉันคิดว่าคุณพลาดส่วนนั้นไป
Ali1S232

@Gajoo นั่นคือจุดที่เกี่ยวกับการสอดแทรกในขั้นตอนที่ 3 อาจไม่ควรเป็นแบบสอดเพราะมันเป็นขั้นตอนสำคัญของกระบวนการทั้งหมด
Trevor Powell

2

คุณจำเป็นต้องรู้ว่าทางใดที่รูปหลายเหลี่ยมนั้นถูกกำหนด

หากคุณไม่ทราบสิ่งนี้คุณสามารถคำนวณได้โดยการคำนวณพื้นที่ของรูปหลายเหลี่ยม:

float Polygon::area() {
    float result = 0.0f;

    for(int a = 0; a < vertexCount; a ++) {
        int b = (a+1) % vertexCount;
        result += vertices[a].x * vertices[b].y;
        result -= vertices[a].y * vertices[b].x;
    }

    return result * .5f;
}

สัญญาณของผล (บวกหรือลบ) จะบอกคุณไม่ว่าจะเป็นตามเข็มนาฬิกาหรือทวนเข็มนาฬิกา คุณต้องลองทำสิ่งนี้เพื่อดูว่าทางไหนเหมาะกับคุณเพราะมันขึ้นอยู่กับระบบพิกัดของคุณ

ถ้ารูปร่างตามเข็มนาฬิกา:

  • สิ่งมีชีวิตที่กำลังเดินไปข้างหน้าจะมีรูปร่างตามเข็มนาฬิกาและ
  • สิ่งมีชีวิตที่เกิดขึ้นย้อนหลังกลมเป็นไปทวนเข็มนาฬิกา

ถ้ารูปร่างทวนเข็มนาฬิกา:

  • สิ่งมีชีวิตที่กำลังเดินไปข้างหน้าจะมีรูปร่างเป็นทวนเข็มนาฬิกาและ
  • สิ่งมีชีวิตที่เกิดขึ้นย้อนหลังกลมเป็นไปตามเข็มนาฬิกา

0

ดูเหมือนว่าเทรเวอร์จะครอบคลุมคำถามนี้แล้ว แต่นี่เป็นวิธีแก้ปัญหาของฉัน:

  1. คำนวณพื้นที่ครอบคลุมรูปร่างของคุณความหมาย

    area = 0
    foreach (edge in shape)
        area += edge.begin.x * edge.end.y - edge.begin.y * edge.end.x
  2. การใช้พื้นที่คำนวณข้างต้นคุณสามารถบอกได้อย่างง่ายดายว่ารูปร่างนั้นเป็นตามเข็มนาฬิกาหรือไม่ มันคือทวนเข็มนาฬิกาหากพื้นที่ต่ำกว่าศูนย์

  3. ตรวจสอบว่าวัตถุ (คือ) กำลังเคลื่อนที่ในลักษณะเดียวกันกับจุดยอดหรือในทิศทางตรงกันข้าม


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