📜  线段上点的方向

📅  最后修改于: 2021-04-29 10:04:08             🧑  作者: Mango

给定点P从线段的方向仅表示给定点P和线段的坐标(例如AB),我们必须确定线段P的方向。那就是该点位于线段的右侧还是线段的左侧。

该点可能位于线段的后面,在这种情况下,我们通过延伸线段并确定点的方向来假设一条假想线。

*只有三种情况,该点在左侧,右侧或在线段本身上。
这是一个非常基本的问题,在线地图中的路线通常会遇到该问题,
示例:假设用户A必须转到下图中的点C,该用户首先到达点B,但此后用户A如何知道他必须向右转还是向左转。

从线段知道点的方向还可以作为构建模块来解决更复杂的问题,例如:

  • 线段相交:查找两个线段是否相交
  • 一组点的凸包

我们将使用的坐标系是笛卡尔平面,因为大多数二维问题都使用笛卡尔平面,并且由于这是二维问题。
向量代数的叉积可以解决此问题
两个点A和B的叉积为: A x * B y – A y * B x
其中A x和A y分别是A的x和y坐标。同样,B x和B y分别是B的x和y坐标。
叉积具有有趣的属性,可用于确定线段中点的方向。也就是说,当且仅当这些点在原点(0,0)处的角度为逆时针时,两个点的叉积才为正。相反,当且仅当这些点在原点的角度为顺时针方向时,叉积为负。
一个例子肯定会澄清这一点
在下图中,角度BOP为逆时针,并且BXP的叉积= 29 * 28 – 15 *(-15)= 1037,为正。

这有助于我们得出以下结论:右侧的点必须具有正的叉积,而左侧的点必须具有负的叉积。还要注意,我们假设线段的一个点为原点,因此我们需要转换任何三点系统,以使线段的一个点为原点。

以下示例解释了该概念
将三个点A,B和P转换为A’,B’P’ ,以A为原点(这可以简单地通过从点P和B减去A的坐标来完成),然后计算叉积:59 * 18 –(-25)* 18 = 2187
由于这是肯定的,所以点P在线段AB的右侧。

C++
// C++ Program to Determine Direction of Point
// from line segment
#include 
using namespace std;
 
// structure for point in cartesian plane.
struct point {
    int x, y;
};
 
// constant integers for directions
const int RIGHT = 1, LEFT = -1, ZERO = 0;
 
int directionOfPoint(point A, point B, point P)
{
    // subtracting co-ordinates of point A from
    // B and P, to make A as origin
    B.x -= A.x;
    B.y -= A.y;
    P.x -= A.x;
    P.y -= A.y;
 
    // Determining cross Product
    int cross_product = B.x * P.y - B.y * P.x;
 
    // return RIGHT if cross product is positive
    if (cross_product > 0)
        return RIGHT;
 
    // return LEFT if cross product is negative
    if (cross_product < 0)
        return LEFT;
 
    // return ZERO if cross product is zero.
    return ZERO;
}
 
// Driver code
int main()
{
    point A, B, P;
    A.x = -30;
    A.y = 10; // A(-30, 10)
    B.x = 29;
    B.y = -15; // B(29, -15)
    P.x = 15;
    P.y = 28; // P(15, 28)
 
    int direction = directionOfPoint(A, B, P);
    if (direction == 1)
        cout << "Right Direction" << endl;
    else if (direction == -1)
        cout << "Left Direction" << endl;
    else
        cout << "Point is on the Line" << endl;
    return 0;
}


Java
// Java Program to Determine Direction of Point
// from line segment
class GFG
{
 
// structure for point in cartesian plane.
static class point
{
    int x, y;
};
 
// constant integers for directions
static int RIGHT = 1, LEFT = -1, ZERO = 0;
 
static int directionOfPoint(point A,
                            point B, point P)
{
    // subtracting co-ordinates of point A
    // from B and P, to make A as origin
    B.x -= A.x;
    B.y -= A.y;
    P.x -= A.x;
    P.y -= A.y;
 
    // Determining cross Product
    int cross_product = B.x * P.y - B.y * P.x;
 
    // return RIGHT if cross product is positive
    if (cross_product > 0)
        return RIGHT;
 
    // return LEFT if cross product is negative
    if (cross_product < 0)
        return LEFT;
 
    // return ZERO if cross product is zero.
    return ZERO;
}
 
// Driver code
public static void main(String[] args)
{
    point A = new point(),
          B = new point(), P = new point();
    A.x = -30;
    A.y = 10; // A(-30, 10)
    B.x = 29;
    B.y = -15; // B(29, -15)
    P.x = 15;
    P.y = 28; // P(15, 28)
 
    int direction = directionOfPoint(A, B, P);
    if (direction == 1)
        System.out.println("Right Direction");
    else if (direction == -1)
        System.out.println("Left Direction");
    else
        System.out.println("Point is on the Line");
    }
}
 
// This code is contributed
// by Princi Singh


Python3
# Python3 program to determine direction
# of point from line segment
  
# Structure for point in cartesian plane.
class point:
     
    def __init__(self):
         
        self.x = 0
        self.y = 0
  
# Constant integers for directions
RIGHT = 1
LEFT = -1
ZERO = 0
  
def directionOfPoint(A, B, P):
     
    global RIGHT, LEFT, ZERO
     
    # Subtracting co-ordinates of
    # point A from B and P, to
    # make A as origin
    B.x -= A.x
    B.y -= A.y
    P.x -= A.x
    P.y -= A.y
  
    # Determining cross Product
    cross_product = B.x * P.y - B.y * P.x
  
    # Return RIGHT if cross product is positive
    if (cross_product > 0):
        return RIGHT
         
    # Return LEFT if cross product is negative
    if (cross_product < 0):
        return LEFT
  
    # Return ZERO if cross product is zero
    return ZERO
 
# Driver code
if __name__=="__main__":
     
    A = point()
    B = point()
    P = point()
     
    A.x = -30
    A.y = 10 # A(-30, 10)
    B.x = 29
    B.y = -15 # B(29, -15)
    P.x = 15
    P.y = 28 # P(15, 28)
  
    direction = directionOfPoint(A, B, P)
     
    if (direction == 1):
        print("Right Direction")
    elif (direction == -1):
        print("Left Direction")
    else:
        print("Point is on the Line")
 
# This code is contributed by rutvik_56


C#
// C# Program to Determine Direction of Point
// from line segment
using System;
using System.Collections.Generic;
 
class GFG
{
 
// structure for point in cartesian plane.
public class point
{
    public int x, y;
};
 
// constant integers for directions
static int RIGHT = 1, LEFT = -1, ZERO = 0;
 
static int directionOfPoint(point A,
                            point B, point P)
{
    // subtracting co-ordinates of point A
    // from B and P, to make A as origin
    B.x -= A.x;
    B.y -= A.y;
    P.x -= A.x;
    P.y -= A.y;
 
    // Determining cross Product
    int cross_product = B.x * P.y - B.y * P.x;
 
    // return RIGHT if cross product is positive
    if (cross_product > 0)
        return RIGHT;
 
    // return LEFT if cross product is negative
    if (cross_product < 0)
        return LEFT;
 
    // return ZERO if cross product is zero.
    return ZERO;
}
 
// Driver code
public static void Main(String[] args)
{
    point A = new point(),
          B = new point(),
          P = new point();
    A.x = -30;
    A.y = 10; // A(-30, 10)
    B.x = 29;
    B.y = -15; // B(29, -15)
    P.x = 15;
    P.y = 28; // P(15, 28)
 
    int direction = directionOfPoint(A, B, P);
    if (direction == 1)
        Console.WriteLine("Right Direction");
    else if (direction == -1)
        Console.WriteLine("Left Direction");
    else
        Console.WriteLine("Point is on the Line");
    }
}
 
// This code is contributed by 29AjayKumar


输出:

Right Direction