จะบอกได้อย่างไรว่าจุดอยู่ทางด้านขวาหรือด้านซ้ายของเส้น


130

ฉันมีชุดของคะแนน ฉันต้องการแยกออกเป็น 2 ชุดที่แตกต่างกัน ในการทำเช่นนี้ฉันเลือกจุดสองจุด ( aและb ) แล้วลากเส้นจินตภาพระหว่างทั้งสอง ตอนนี้ฉันต้องการให้คะแนนทั้งหมดที่เหลือจากบรรทัดนี้ในชุดเดียวและคะแนนที่อยู่ตรงจากบรรทัดนี้ในอีกชุดหนึ่ง

ฉันจะบอกจุดz ที่กำหนดได้อย่างไรว่าอยู่ทางซ้ายหรือในเซตด้านขวา? ฉันพยายามคำนวณมุมระหว่างazb - มุมที่เล็กกว่า 180 อยู่ทางด้านขวามือมากกว่า 180 ทางด้านซ้ายมือ - แต่เนื่องจากคำจำกัดความของ ArcCos มุมที่คำนวณจะมีขนาดเล็กกว่า 180 °เสมอ มีสูตรคำนวณมุมที่มากกว่า 180 ° (หรือสูตรอื่นให้เลือกด้านขวาหรือซ้าย) หรือไม่?


ขวาหรือซ้ายถูกกำหนดอย่างไร? A) ในแง่ของการมองจาก P1 ไปยัง P2 หรือ B) ทางซ้ายหรือขวาของเส้นในระนาบ
phkahler

2
เพื่อชี้แจงในส่วนที่สองของคำถามของคุณคุณสามารถใช้ atan2 () แทน acos () เพื่อคำนวณมุมที่ถูกต้อง อย่างไรก็ตามการใช้ผลิตภัณฑ์ผสมข้ามเป็นทางออกที่ดีที่สุดตามที่ Eric Bainville ชี้ให้เห็น
dionyziz

วิธีแก้ปัญหาหลายวิธีด้านล่างใช้ไม่ได้ผลเนื่องจากให้คำตอบที่ตรงกันข้ามหากคุณเปลี่ยนจุด a และ b (จุดที่เราใช้กำหนดเส้นของเรา) ฉันให้วิธีแก้ปัญหาใน Clojure ที่จัดเรียงสองจุดตามศัพท์ทางศัพท์ก่อนที่จะเปรียบเทียบกับจุดที่สาม
Purplejacket

คำตอบ:


202

ใช้เครื่องหมายของดีเทอร์มิแนนต์ของเวกเตอร์จุดค้นหาอยู่(AB,AM)ที่ไหนM(X,Y):

position = sign((Bx - Ax) * (Y - Ay) - (By - Ay) * (X - Ax))

มันเป็น0ในบรรทัดและ+1ในอีกด้านหนึ่ง-1ในด้านอื่น ๆ


10
+1 ดีและสิ่งหนึ่งที่ควรระวัง: ข้อผิดพลาดในการปัดเศษอาจเป็นเรื่องที่น่ากังวลเมื่อประเด็นนั้นอยู่ใกล้เส้นมาก ไม่ใช่ปัญหาสำหรับการใช้งานส่วนใหญ่แต่จะกัดคนเป็นครั้งคราว
Stephen Canon

16
หากคุณพบว่าตัวเองตกอยู่ในสถานการณ์ที่ข้อผิดพลาดในการปัดเศษในการทดสอบนี้ทำให้เกิดปัญหาคุณจะต้องค้นหา "Fast Robust Predicates for Computational Geometry" ของ Jon Shewchuk
Stephen Canon

14
เพื่อความชัดเจนนี่จะเหมือนกับองค์ประกอบ Z ของผลคูณไขว้ระหว่างเส้น (ba) และเวกเตอร์ไปยังจุดจาก (ma) ในคลาสเวกเตอร์ที่คุณชื่นชอบ: position = sign ((ba) .cross (ma) [2])
larsmoa

3
จะไม่สลับ A & B ให้อยู่ในบรรทัดเดียวกัน แต่เปลี่ยนเครื่องหมายของpositions?
Jayen

6
ใช่. A, B กำหนดแนวเช่นใน "ทางซ้ายของคุณเมื่อยืนที่ A และมองไปที่ B"
Eric Bainville

224

ลองใช้รหัสนี้ซึ่งใช้ประโยชน์จากผลิตภัณฑ์ที่หลากหลาย :

public bool isLeft(Point a, Point b, Point c){
     return ((b.X - a.X)*(c.Y - a.Y) - (b.Y - a.Y)*(c.X - a.X)) > 0;
}

โดยที่a = line point 1; b = จุดเส้น 2; c = ชี้เพื่อตรวจสอบ

ถ้าสูตรเท่ากับ 0 จุดจะเป็นโคลิเนียร์

ถ้าเส้นเป็นแนวนอนสิ่งนี้จะส่งกลับจริงถ้าจุดอยู่เหนือเส้น


6
ถ้าเส้นเป็นแนวตั้งแล้ว?
Tofeeq Ahmad

9
คุณหมายถึงผลิตภัณฑ์ดอทหรือเปล่า
Baiyan Huang

13
@lzprgmr: ไม่นี่คือผลคูณไขว้เทียบเท่ากับดีเทอร์มิแนนต์ของเมทริกซ์ 2 มิติ พิจารณาเมทริกซ์ 2 มิติที่กำหนดโดยแถว (a, b) และ (c, d) ดีเทอร์มิแนนต์คือ ad - bc รูปแบบด้านบนกำลังเปลี่ยนเส้นที่แทนด้วยจุด 2 จุดให้เป็นเวกเตอร์หนึ่ง (a, b) จากนั้นกำหนดเวกเตอร์อื่นโดยใช้ PointA และ PointC เพื่อให้ได้ (c, d): (a, b) = (PointB.x - PointA.x, PointB.y - PointA.y) (c, d) = (PointC.x - PointA.x, PointC.y - PointA.y) ดีเทอร์มิแนนต์จึงเป็นไปตามที่ระบุไว้ในโพสต์
AndyG

6
ฉันคิดว่าความสับสนว่านี่เป็นผลิตภัณฑ์ข้ามหรือผลิตภัณฑ์จุดเป็นเพราะมันเป็นสองมิติ มันเป็นผลิตภัณฑ์ข้ามในสองมิติ: mathworld.wolfram.com/CrossProduct.html
brianmearns

4
สำหรับสิ่งที่คุ้มค่าสิ่งนี้สามารถทำให้ง่ายขึ้นเล็กน้อยreturn (b.x - a.x)*(c.y - a.y) > (b.y - a.y)*(c.x - a.x);แต่คอมไพเลอร์อาจปรับให้เหมาะสมที่สุด
Nicu Stiurca

44

คุณดูเครื่องหมายของดีเทอร์มิแนนต์ของ

| x2-x1  x3-x1 |
| y2-y1  y3-y1 |

มันจะเป็นบวกสำหรับจุดในด้านหนึ่งและอีกด้านหนึ่งเป็นลบ (และเป็นศูนย์สำหรับจุดบนเส้นนั้นเอง)


1
ขยายความเกี่ยวกับคำตอบนี้ในกรณีที่ผู้คนไม่ทราบว่าผลิตภัณฑ์ครอสมีลักษณะอย่างไร ขั้นตอนต่อไปของภาพคือ ((x2-x1) * (y3-y1)) - ((y2 - y1) * (x3-x1))
Franky Rivera

10

เวกเตอร์ (y1 - y2, x2 - x1)ตั้งฉากกับเส้นและชี้ไปทางขวาเสมอ (หรือชี้ไปทางซ้ายเสมอหากการวางแนวระนาบแตกต่างจากของฉัน)

จากนั้นคุณสามารถคำนวณผลคูณดอทของเวกเตอร์นั้นและ(x3 - x1, y3 - y1)กำหนดว่าจุดนั้นอยู่ที่ด้านเดียวกันของเส้นเป็นเวกเตอร์ตั้งฉาก (ผลิตภัณฑ์จุด> 0) หรือไม่


5

ใช้สมการของเส้น abรับพิกัด x บนเส้นที่พิกัด y เดียวกันกับจุดที่จะจัดเรียง

  • ถ้าจุด x> เส้น x จุดอยู่ทางขวาของเส้น
  • ถ้าจุด x <เส้น x จุดอยู่ทางซ้ายของเส้น
  • ถ้าจุด x == ของเส้น x จุดอยู่บนเส้น

นี่เป็นสิ่งที่ผิดเพราะอย่างที่คุณเห็นจากความคิดเห็นของ Aaginor ในคำตอบแรกเราไม่ต้องการคิดว่าจุดนั้นอยู่ทางซ้ายหรือขวาของเส้นตรง AB หรือไม่เช่นถ้าคุณยืนอยู่บน A และมอง ไปทาง B อยู่ทางซ้ายหรือทางขวา?
dionyziz

1
@dionyziz - หือ? คำตอบของฉันไม่ได้กำหนด "ทิศทาง" ให้กับบรรทัดผ่าน AB คำตอบของฉันถือว่า "ซ้าย" คือทิศทาง -x ของระบบ corrdinate คำตอบที่ยอมรับได้เลือกที่จะกำหนดเวกเตอร์ AB และกำหนดด้านซ้ายโดยใช้ผลิตภัณฑ์ไขว้ คำถามเดิมไม่ได้ระบุความหมายของ "ซ้าย"
mbeckish

3
หมายเหตุ: หากคุณใช้แนวทางนี้ (แทนที่จะเป็นผลิตภัณฑ์ข้ามผลิตภัณฑ์ที่ได้รับการอนุมัติเป็นคำตอบ) โปรดระวังข้อผิดพลาดเนื่องจากเส้นเข้าใกล้แนวนอน ข้อผิดพลาดทางคณิตศาสตร์เพิ่มขึ้นและมีค่าไม่สิ้นสุดหากอยู่ในแนวนอน วิธีแก้ไขคือใช้แกนใดก็ตามที่มีเดลต้ามากกว่าระหว่างจุดทั้งสอง (หรืออาจจะเล็กกว่าเดลต้า.. นี่คือส่วนบนของหัวของฉัน)
ToolmakerSteve

นี่คือสิ่งที่ฉันกำลังมองหา ฉันไม่อยากรู้ว่า A อยู่เหนือหรือต่ำกว่า B ฉันแค่อยากรู้ว่ามันเหลือ (ทิศทาง x ลบ) ของเส้น!
Jayen

5

ก่อนอื่นให้ตรวจสอบว่าคุณมีเส้นแนวตั้งหรือไม่:

if (x2-x1) == 0
  if x3 < x2
     it's on the left
  if x3 > x2
     it's on the right
  else
     it's on the line

จากนั้นคำนวณความชัน: m = (y2-y1)/(x2-x1)

y - y1 = m*(x-x1) + y1จากนั้นสร้างสมการของเส้นโดยใช้แบบฟอร์มจุดลาด: เพื่อประโยชน์ในการอธิบายของฉันให้ลดความซับซ้อนให้เป็นรูปแบบลาดตัดขวาง (ไม่จำเป็นในอัลกอริทึมของคุณ):y = mx+b(ไม่จำเป็นต้องอยู่ในขั้นตอนวิธีการของคุณ):

ตอนนี้เสียบ(x3, y3)สำหรับxและy. นี่คือรหัสเทียมบางส่วนที่ให้รายละเอียดสิ่งที่ควรเกิดขึ้น:

if m > 0
  if y3 > m*x3 + b
    it's on the left
  else if y3 < m*x3 + b
    it's on the right
  else
    it's on the line
else if m < 0
  if y3 < m*x3 + b
    it's on the left
  if y3 > m*x3+b
    it's on the right
  else
    it's on the line
else
  horizontal line; up to you what you do

3
ล้มเหลว: การคำนวณความลาดชันไม่ถูกต้องสำหรับเส้นแนวตั้ง ไม่มีที่สิ้นสุด if / else สิ่ง ไม่แน่ใจว่านั่นคือสิ่งที่ OP หมายถึงทางซ้าย / ขวา - ถ้ามองอย่างนั้นหมุน 90 องศาจะทำให้โค้ดนี้ลดลงครึ่งหนึ่งเนื่องจาก "ด้านบน" จะเป็นขวาหรือซ้าย
phkahler

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

2
@phkahler แก้ไขปัญหาเส้นแนวตั้ง ไม่ใช่ความล้มเหลวในการลืมกรณีทดสอบหนึ่งกรณี แต่ขอบคุณสำหรับคำพูดที่ดี "Endless if / else" คือการอธิบายทฤษฎีทางคณิตศาสตร์ ไม่มีอะไรในคำถามของ OP กล่าวถึงการเขียนโปรแกรม @woodchips แก้ไขปัญหาเส้นแนวตั้ง ความชันคือตัวแปร m; ฉันจะตรวจสอบว่าเมื่อใดเป็นบวกหรือลบ
maksim

5

ฉันใช้สิ่งนี้ใน java และทำการทดสอบหน่วย (แหล่งที่มาด้านล่าง) วิธีแก้ปัญหาข้างต้นไม่ได้ผล รหัสนี้ผ่านการทดสอบหน่วย หากใครพบว่าการทดสอบหน่วยที่ไม่ผ่านโปรดแจ้งให้เราทราบ

รหัส: หมายเหตุ: nearlyEqual(double,double)ส่งกลับค่าจริงหากตัวเลขทั้งสองอยู่ใกล้กันมาก

/*
 * @return integer code for which side of the line ab c is on.  1 means
 * left turn, -1 means right turn.  Returns
 * 0 if all three are on a line
 */
public static int findSide(
        double ax, double ay, 
        double bx, double by,
        double cx, double cy) {
    if (nearlyEqual(bx-ax,0)) { // vertical line
        if (cx < bx) {
            return by > ay ? 1 : -1;
        }
        if (cx > bx) {
            return by > ay ? -1 : 1;
        } 
        return 0;
    }
    if (nearlyEqual(by-ay,0)) { // horizontal line
        if (cy < by) {
            return bx > ax ? -1 : 1;
        }
        if (cy > by) {
            return bx > ax ? 1 : -1;
        } 
        return 0;
    }
    double slope = (by - ay) / (bx - ax);
    double yIntercept = ay - ax * slope;
    double cSolution = (slope*cx) + yIntercept;
    if (slope != 0) {
        if (cy > cSolution) {
            return bx > ax ? 1 : -1;
        }
        if (cy < cSolution) {
            return bx > ax ? -1 : 1;
        }
        return 0;
    }
    return 0;
}

นี่คือการทดสอบหน่วย:

@Test public void testFindSide() {
    assertTrue("1", 1 == Utility.findSide(1, 0, 0, 0, -1, -1));
    assertTrue("1.1", 1 == Utility.findSide(25, 0, 0, 0, -1, -14));
    assertTrue("1.2", 1 == Utility.findSide(25, 20, 0, 20, -1, 6));
    assertTrue("1.3", 1 == Utility.findSide(24, 20, -1, 20, -2, 6));

    assertTrue("-1", -1 == Utility.findSide(1, 0, 0, 0, 1, 1));
    assertTrue("-1.1", -1 == Utility.findSide(12, 0, 0, 0, 2, 1));
    assertTrue("-1.2", -1 == Utility.findSide(-25, 0, 0, 0, -1, -14));
    assertTrue("-1.3", -1 == Utility.findSide(1, 0.5, 0, 0, 1, 1));

    assertTrue("2.1", -1 == Utility.findSide(0,5, 1,10, 10,20));
    assertTrue("2.2", 1 == Utility.findSide(0,9.1, 1,10, 10,20));
    assertTrue("2.3", -1 == Utility.findSide(0,5, 1,10, 20,10));
    assertTrue("2.4", -1 == Utility.findSide(0,9.1, 1,10, 20,10));

    assertTrue("vertical 1", 1 == Utility.findSide(1,1, 1,10, 0,0));
    assertTrue("vertical 2", -1 == Utility.findSide(1,10, 1,1, 0,0));
    assertTrue("vertical 3", -1 == Utility.findSide(1,1, 1,10, 5,0));
    assertTrue("vertical 3", 1 == Utility.findSide(1,10, 1,1, 5,0));

    assertTrue("horizontal 1", 1 == Utility.findSide(1,-1, 10,-1, 0,0));
    assertTrue("horizontal 2", -1 == Utility.findSide(10,-1, 1,-1, 0,0));
    assertTrue("horizontal 3", -1 == Utility.findSide(1,-1, 10,-1, 0,-9));
    assertTrue("horizontal 4", 1 == Utility.findSide(10,-1, 1,-1, 0,-9));

    assertTrue("positive slope 1", 1 == Utility.findSide(0,0, 10,10, 1,2));
    assertTrue("positive slope 2", -1 == Utility.findSide(10,10, 0,0, 1,2));
    assertTrue("positive slope 3", -1 == Utility.findSide(0,0, 10,10, 1,0));
    assertTrue("positive slope 4", 1 == Utility.findSide(10,10, 0,0, 1,0));

    assertTrue("negative slope 1", -1 == Utility.findSide(0,0, -10,10, 1,2));
    assertTrue("negative slope 2", -1 == Utility.findSide(0,0, -10,10, 1,2));
    assertTrue("negative slope 3", 1 == Utility.findSide(0,0, -10,10, -1,-2));
    assertTrue("negative slope 4", -1 == Utility.findSide(-10,10, 0,0, -1,-2));

    assertTrue("0", 0 == Utility.findSide(1, 0, 0, 0, -1, 0));
    assertTrue("1", 0 == Utility.findSide(0,0, 0, 0, 0, 0));
    assertTrue("2", 0 == Utility.findSide(0,0, 0,1, 0,2));
    assertTrue("3", 0 == Utility.findSide(0,0, 2,0, 1,0));
    assertTrue("4", 0 == Utility.findSide(1, -2, 0, 0, -1, 2));
}

2

สมมติว่าจุดคือ (Axe, Ay) (Bx, By) และ (Cx, Cy) คุณต้องคำนวณ:

(Bx - ขวาน) * (Cy - Ay) - (By - Ay) * (Cx - Axe)

สิ่งนี้จะเท่ากับศูนย์ถ้าจุด C อยู่บนเส้นที่เกิดจากจุด A และ B และจะมีเครื่องหมายต่างกันขึ้นอยู่กับด้านข้าง ด้านใดขึ้นอยู่กับการวางแนวของพิกัด (x, y) ของคุณ แต่คุณสามารถใส่ค่าทดสอบสำหรับ A, B และ C ลงในสูตรนี้เพื่อกำหนดว่าค่าลบอยู่ทางซ้ายหรือทางขวา


2

ฉันต้องการหาวิธีแก้ปัญหาที่ได้รับแรงบันดาลใจจากฟิสิกส์

ลองนึกภาพแรงที่กระทำตามเส้นและคุณกำลังวัดแรงบิดของแรงเกี่ยวกับจุดนั้น ถ้าแรงบิดเป็นบวก (ทวนเข็มนาฬิกา) จุดจะอยู่ทาง "ซ้าย" ของเส้น แต่ถ้าแรงบิดเป็นลบจุดนั้นจะเป็น "ทางขวา" ของเส้น

ดังนั้นถ้าเวกเตอร์แรงเท่ากับช่วงของจุดสองจุดที่กำหนดเส้น

fx = x_2 - x_1
fy = y_2 - y_1

คุณทดสอบด้านข้างของจุด(px,py)ตามสัญลักษณ์ของการทดสอบต่อไปนี้

var torque = fx*(py-y_1)-fy*(px-x_1)
if  torque>0  then
     "point on left side"
else if torque <0 then
     "point on right side"  
else
     "point on line"
end if

1

โดยพื้นฐานแล้วฉันคิดว่ามีวิธีแก้ปัญหาที่ง่ายกว่ามากและตรงไปตรงมาสำหรับรูปหลายเหลี่ยมใด ๆ สมมติว่าประกอบด้วยจุดยอดสี่จุด (p1, p2, p3, p4) ค้นหาจุดยอดสองจุดที่ตรงกันข้ามกันสุดขั้วในรูปหลายเหลี่ยมในอีกรูป คำค้นหาตัวอย่างเช่นจุดยอดซ้ายบนสุด (สมมติว่า p1) และจุดยอดตรงข้ามซึ่งอยู่ด้านขวาล่างสุด (สมมติว่า) ดังนั้นเมื่อพิจารณาจากจุดทดสอบ C (x, y) ตอนนี้คุณต้องตรวจสอบซ้ำระหว่าง C และ p1 และ C และ p4:

ถ้า cx> p1x AND cy> p1y ==> หมายความว่า C ต่ำกว่าและอยู่ทางขวาของ p1 ถัดไปถ้า cx <p2x AND cy <p2y ==> หมายความว่า C อยู่บนและทางซ้ายของ p4

สรุปได้ว่า C อยู่ภายในสี่เหลี่ยมผืนผ้า

ขอบคุณ :)


1
(1) ตอบคำถามที่แตกต่างจากที่ถาม? ดูเหมือนการทดสอบ "กล่องขอบเขต" เมื่อรูปสี่เหลี่ยมผืนผ้าอยู่ในแนวเดียวกันกับทั้งสองแกน (2) รายละเอียดเพิ่มเติม: ตั้งสมมติฐานเกี่ยวกับความสัมพันธ์ที่เป็นไปได้ระหว่าง 4 คะแนน ตัวอย่างเช่นใช้รูปสี่เหลี่ยมผืนผ้าและหมุน 45 องศาเพื่อให้คุณมีเพชร ไม่มี "จุดบนซ้าย" ในเพชรเม็ดนั้น จุดซ้ายสุดไม่ได้อยู่บนสุดหรือล่างสุด และแน่นอนว่า 4 จุดสามารถสร้างรูปร่างได้แม้กระทั่งคนแปลกหน้า ตัวอย่างเช่น 3 จุดอาจอยู่ห่างออกไปในทิศทางเดียวและจุดที่ 4 ในทิศทางอื่น พยายามต่อไป!
ToolmakerSteve

1

คำตอบของ @ AVB ในทับทิม

det = Matrix[
  [(x2 - x1), (x3 - x1)],
  [(y2 - y1), (y3 - y1)]
].determinant

ถ้าdetเป็นบวกด้านบนถ้าเป็นลบด้านล่าง ถ้า 0 แสดงว่าอยู่ในบรรทัด


1

นี่คือเวอร์ชันอีกครั้งโดยใช้ตรรกะข้ามผลิตภัณฑ์ซึ่งเขียนด้วย Clojure

(defn is-left? [line point]
  (let [[[x1 y1] [x2 y2]] (sort line)
        [x-pt y-pt] point]
    (> (* (- x2 x1) (- y-pt y1)) (* (- y2 y1) (- x-pt x1)))))

ตัวอย่างการใช้งาน:

(is-left? [[-3 -1] [3 1]] [0 10])
true

ซึ่งก็คือจุด (0, 10) อยู่ทางซ้ายของเส้นที่กำหนดโดย (-3, -1) และ (3, 1)

หมายเหตุ: การใช้งานนี้ช่วยแก้ปัญหาที่ไม่มีคนอื่น (จนถึงตอนนี้) ทำ! ลำดับเรื่องเมื่อให้คะแนนที่กำหนดเส้น กล่าวคือเป็น "เส้นกำกับ" ในแง่หนึ่ง ดังนั้นด้วยรหัสด้านบนการเรียกใช้นี้จะสร้างผลลัพธ์ของtrue:

(is-left? [[3 1] [-3 -1]] [0 10])
true

นั่นเป็นเพราะข้อมูลโค้ดนี้:

(sort line)

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

(is-left? [[1 1] [3 1]] [10 1])
false

0

อีกทางเลือกหนึ่งในการรับความรู้สึกของการแก้ปัญหาโดยเน็ตเทอร์คือการเข้าใจผลกระทบทางเรขาคณิตเล็กน้อย

ให้PQR = [P, Q, R] เป็นจุดที่รูปแบบเครื่องบินที่ถูกแบ่งออกเป็น 2 ด้านโดยบรรทัด[P, R] เราต้องหาว่าสองจุดบนระนาบpqr , A, B อยู่ด้านเดียวกันหรือไม่

จุดTใด ๆบนระนาบ pqr สามารถแทนด้วยเวกเตอร์ 2 ตัว: v = PQ และu = RQ เป็น:

T '= TQ = ฉัน * v + j * u

ตอนนี้ผลกระทบทางเรขาคณิต:

  1. i + j = 1: T ในบรรทัด pr
  2. i + j <1: T บน Sq
  3. i + j> 1: T บน Snq
  4. ผม + j = 0: T = Q
  5. i + j <0: T บน Sq และหลัง Q

i+j: <0 0 <1 =1 >1 ---------Q------[PR]--------- <== this is PQR plane ^ pr line

โดยทั่วไปแล้ว

  • i + j คือการวัดระยะทางที่ T อยู่ห่างจาก Q หรือเส้น [P, R]และ
  • เครื่องหมายของi + j-1 แสดงถึงความไม่อยู่นิ่งของ T

ความสำคัญทางเรขาคณิตอื่น ๆ ของiและj (ไม่เกี่ยวข้องกับโซลูชันนี้) คือ:

  • i , jคือสเกลาร์สำหรับ T ในระบบพิกัดใหม่โดยที่v, uคือแกนใหม่และQคือจุดกำเนิดใหม่
  • i , jสามารถมองได้ว่าเป็นแรงดึงสำหรับP, Rตามลำดับ ยิ่งiใหญ่เท่าไหร่ T ที่อยู่ห่างจากR (ดึงจากPมากขึ้น)

ค่าของi, jสามารถหาได้จากการแก้สมการ:

i*vx + j*ux = T'x
i*vy + j*uy = T'y
i*vz + j*uz = T'z

ดังนั้นเราจึงได้รับ 2 คะแนนคือ A, B บนเครื่องบิน:

A = a1 * v + a2 * u B = b1 * v + b2 * u

ถ้า A, B อยู่ด้านเดียวกันสิ่งนี้จะเป็นจริง:

sign(a1+a2-1) = sign(b1+b2-1)

โปรดทราบว่าสิ่งนี้ใช้กับคำถาม: A, B อยู่ด้านเดียวกันของระนาบ [P, Q, R]ซึ่ง:

T = i * P + j * Q + k * R

และi + j + k = 1หมายความว่า T อยู่บนระนาบ [P, Q, R] และเครื่องหมายของi + j + k-1แสดงถึงความเป็นไปได้ จากสิ่งนี้เรามี:

A = a1 * P + a2 * Q + a3 * R B = b1 * P + b2 * Q + b3 * R

และ A, B อยู่ด้านเดียวกันของระนาบ [P, Q, R] ถ้า

sign(a1+a2+a3-1) = sign(b1+b2+b3-1)

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