📜  查找截面内线的交点

📅  最后修改于: 2021-05-04 17:53:17             🧑  作者: Mango

给定y = mx + b形式的二维空间中的N条线和垂直截面。我们需要找出给定截面内是否有交点。
例子:

在下图中,有四条线,L1:y = x + 2 L2:y = -x + 7 L3:y = -3 L4:y = 2x – 7,垂直截面从x = 2到x = 4 我们可以看到,在上图中,线L1和L2的交点位于截面之间。

我们可以使用排序解决此问题。首先,我们将计算每条线与垂直截面的边界的交点并将其成对存储。我们只需要将交叉点的y坐标存储为一对,因为x坐标等于边界本身。现在,我们将基于它们与左边界的交集对它们进行排序。之后,我们将一对一地遍历这些对,如果对于任意两个连续对,当前对的第二个值小于前一对的第二个值,则在给定的垂直截面中必须有一个交点。
可以在上图中针对L1和L2看到两个连续对的可能方向。我们可以看到,当第二个值较小时,交点位于垂直截面中。

解决方案的总时间复杂度为O(n logn)

// C++ program to check an intersection point
// inside a given vertical section
#include 
using namespace std;
  
// structure to represent a line
struct line {
    int m, b;
    line()  { }
    line(int m, int b) : m(m), b(b)  { }
};
  
// Utility method to get Y-cordinate 
// corresponding to x in line l
int getYFromLine(line l, int x)
{
    return (l.m * x + l.b);
}
  
// method returns true if two line cross
// each other between xL and xR range
bool isIntersectionPointInsideSection(line lines[], 
                            int xL, int xR, int N)
{
    pair yBoundary[N];
  
    // first calculating y-values and putting 
    // in boundary pair
    for (int i = 0; i < N; i++) 
        yBoundary[i] = make_pair(getYFromLine(lines[i], xL), 
                               getYFromLine(lines[i], xR));
      
  
    // sorting the pair on the basis of first
    // boundary intersection
    sort(yBoundary, yBoundary + N);
  
    // looping over sorted pairs for comparison
    for (int i = 1; i < N; i++) {
  
        // if current pair's second value is smaller
        // than previous pair's then return true
        if (yBoundary[i].second < yBoundary[i - 1].second) 
            return true;        
    }
  
    return false;
}
  
// Driver code to test above methods
int main()
{
    int N = 4;
    int m[] = { 1, -1, 0, 2 };
    int b[] = { 2, 7, -3, -7 };
  
    // copy values in line struct
    line lines[N];
    for (int i = 0; i < N; i++) {
        lines[i] = line(m[i], b[i]);
  
    int xL = 2;
    int xR = 4;
  
    if (isIntersectionPointInsideSection(lines, xL, xR, N)) {
        cout << "Intersection point lies between " 
             << xL << " and " << xR << endl;
    } else {
        cout << "No Intersection point lies between " 
             << xL << " and " << xR << endl;
    }
}

输出:

Intersection point lies between 2 and 4