📜  给定点可能的四边形数量

📅  最后修改于: 2021-04-26 09:22:04             🧑  作者: Mango

在直角坐标系中给定四个点(x,y)。找到四边形的可能数目,而不是将所有四个点合并而成的数目。
例子:

Input: A=(0, 9), B=(-1, 0), C=(5, -1), D=(5, 9)
Output: Only one quadrilateral is possible (ABCD) in any orientation 

Input: A=(0, 9), B=(-1, 0), C=(5, -1), D=(0, 3)
Output: 3 quadrilaterals are possible (ABCD), (ADBC), (ABDC)

第二个例子的图:
案例2说明

方法:

  1. 我们需要检查给定的点是否相同。如果是,则四边形不为零
  2. 然后,我们需要检查给定的4个点中的3个点中的任何一个是否共线。如果是,则四边形的个数= 0。检查程序以检查三个点是否共线,以检查三个点的共线性。
    1. 现在,对于有效的四边形,有两种可能性:
    2. 如果它是凸的四边形,则只有一个可能的四边形
    3. 如果它是凹的四边形,则有3个可能的四边形

这可以通过如何检查两个给定的线段是否相交来确定?对角线。
凸四边形的情况下,对角线将相交,而在凹四边形的情况下,对角线将不相交。
由于我们不知道这些点的方向,因此我们无法具体确定对角线,因此无法确定四边形的所有不同线段(两个线段中没有公共点)并确定它们是否相交。

请参考该图以了解如何确定四边形的类型:
线段的交点

凸四边形:

凹四边形

如果没有交集= 1,则其为凸四边形,因此可能性= 1
如果没有交集= 0,则其为凹四边形,因此可能性= 3

C++
// C++ implementation of above approach
#include 
using namespace std;
  
struct Point // points
{
    int x;
    int y;
};
  
// determines the orientation of points
int orientation(Point p, Point q, Point r)
{
    int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
  
    if (val == 0)
        return 0;
    return (val > 0) ? 1 : 2;
}
  
// check whether the distinct line segments intersect
bool doIntersect(Point p1, Point q1, Point p2, Point q2)
{
    int o1 = orientation(p1, q1, p2);
    int o2 = orientation(p1, q1, q2);
    int o3 = orientation(p2, q2, p1);
    int o4 = orientation(p2, q2, q1);
  
    if (o1 != o2 && o3 != o4)
        return true;
  
    return false;
}
  
// check if points overlap(similar)
bool similar(Point p1, Point p2)
{
  
    // it is same, we are returning false because
    // quadrilateral is not possible in this case
    if (p1.x == p2.x && p1.y == p2.y)
        return false;
  
    // it is not same, So there is a
    // possibility of a quadrilateral
    return true;
}
  
// check for collinearity
bool collinear(Point p1, Point p2, Point p3)
{
    int x1 = p1.x, y1 = p1.y;
    int x2 = p2.x, y2 = p2.y;
    int x3 = p3.x, y3 = p3.y;
  
    // it is collinear, we are returning false
    // because quadrilateral is not possible in this case
    if ((y3 - y2) * (x2 - x1) == (y2 - y1) * (x3 - x2))
        return false;
  
    // it is not collinear, So there
    // is a possibility of a quadrilateral
    else
        return true;
}
  
int no_of_quads(Point p1, Point p2, Point p3, Point p4)
{
    // ** Checking for cases where no quadrilateral = 0 **
  
    // check if any of the points are same
    bool same = true;
    same = same & similar(p1, p2);
    same = same & similar(p1, p3);
    same = same & similar(p1, p4);
    same = same & similar(p2, p3);
    same = same & similar(p2, p4);
    same = same & similar(p3, p4);
  
    // similar points exist
    if (same == false)
        return 0;
  
    // check for collinearity
    bool coll = true;
    coll = coll & collinear(p1, p2, p3);
    coll = coll & collinear(p1, p2, p4);
    coll = coll & collinear(p1, p3, p4);
    coll = coll & collinear(p2, p3, p4);
  
    // points are collinear
    if (coll == false)
        return 0;
  
    //** Checking for cases where no of quadrilaterals= 1 or 3 **
  
    int check = 0;
  
    if (doIntersect(p1, p2, p3, p4))
        check = 1;
    if (doIntersect(p1, p3, p2, p4))
        check = 1;
    if (doIntersect(p1, p2, p4, p3))
        check = 1;
  
    if (check == 0)
        return 3;
    return 1;
}
  
// Driver code
int main()
{
    struct Point p1, p2, p3, p4;
    // A =(0, 9), B = (-1, 0), C = (5, -1), D=(5, 9)
    p1.x = 0, p1.y = 9;
    p2.x = -1, p2.y = 0;
    p3.x = 5, p3.y = -1;
    p4.x = 5, p4.y = 9;
    cout << no_of_quads(p1, p2, p3, p4) << endl;
  
    // A=(0, 9), B=(-1, 0), C=(5, -1), D=(0, 3)
    p1.x = 0, p1.y = 9;
    p2.x = -1, p2.y = 0;
    p3.x = 5, p3.y = -1;
    p4.x = 0, p4.y = 3;
    cout << no_of_quads(p1, p2, p3, p4) << endl;
  
    // A=(0, 9), B=(0, 10), C=(0, 11), D=(0, 12)
    p1.x = 0, p1.y = 9;
    p2.x = 0, p2.y = 10;
    p3.x = 0, p3.y = 11;
    p4.x = 0, p4.y = 12;
    cout << no_of_quads(p1, p2, p3, p4) << endl;
  
    // A=(0, 9), B=(0, 9), C=(5, -1), D=(0, 3)
    p1.x = 0, p1.y = 9;
    p2.x = 0, p2.y = 9;
    p3.x = 5, p3.y = -1;
    p4.x = 0, p4.y = 3;
    cout << no_of_quads(p1, p2, p3, p4) << endl;
  
    return 0;
}


Java
// Java implementation of above approach
class GFG
{
static class Point // points
{
    int x;
    int y;
}
  
// determines the orientation of points
static int orientation(Point p, Point q, 
                                Point r)
{
    int val = (q.y - p.y) * (r.x - q.x) - 
              (q.x - p.x) * (r.y - q.y);
  
    if (val == 0)
        return 0;
    return (val > 0) ? 1 : 2;
}
  
// check whether the distinct 
// line segments intersect
static boolean doIntersect(Point p1, Point q1, 
                           Point p2, Point q2)
{
    int o1 = orientation(p1, q1, p2);
    int o2 = orientation(p1, q1, q2);
    int o3 = orientation(p2, q2, p1);
    int o4 = orientation(p2, q2, q1);
  
    if (o1 != o2 && o3 != o4)
        return true;
  
    return false;
}
  
// check if points overlap(similar)
static boolean similar(Point p1, Point p2)
{
  
    // it is same, we are returning 
    // false because quadrilateral is 
    // not possible in this case
    if (p1.x == p2.x && p1.y == p2.y)
        return false;
  
    // it is not same, So there is a
    // possibility of a quadrilateral
    return true;
}
  
// check for collinearity
static boolean collinear(Point p1, Point p2, 
                         Point p3)
{
    int x1 = p1.x, y1 = p1.y;
    int x2 = p2.x, y2 = p2.y;
    int x3 = p3.x, y3 = p3.y;
  
    // it is collinear, we are returning 
    // false because quadrilateral is not 
    // possible in this case
    if ((y3 - y2) * 
        (x2 - x1) == (y2 - y1) * 
                     (x3 - x2))
        return false;
  
    // it is not collinear, So there
    // is a possibility of a quadrilateral
    else
        return true;
}
  
static int no_of_quads(Point p1, Point p2, 
                       Point p3, Point p4)
{
    // Checking for cases where 
    // no quadrilateral = 0 
  
    // check if any of the 
    // points are same
    boolean same = true;
    same = same & similar(p1, p2);
    same = same & similar(p1, p3);
    same = same & similar(p1, p4);
    same = same & similar(p2, p3);
    same = same & similar(p2, p4);
    same = same & similar(p3, p4);
  
    // similar points exist
    if (same == false)
        return 0;
  
    // check for collinearity
    boolean coll = true;
    coll = coll & collinear(p1, p2, p3);
    coll = coll & collinear(p1, p2, p4);
    coll = coll & collinear(p1, p3, p4);
    coll = coll & collinear(p2, p3, p4);
  
    // points are collinear
    if (coll == false)
        return 0;
  
    // Checking for cases where 
    // no of quadrilaterals= 1 or 3 
  
    int check = 0;
  
    if (doIntersect(p1, p2, p3, p4))
        check = 1;
    if (doIntersect(p1, p3, p2, p4))
        check = 1;
    if (doIntersect(p1, p2, p4, p3))
        check = 1;
  
    if (check == 0)
        return 3;
    return 1;
}
  
// Driver code
public static void main(String args[])
{
    Point p1, p2, p3, p4;
    p1 = new Point();
    p2 = new Point();
    p3 = new Point();
    p4 = new Point();
      
    // A =(0, 9), B = (-1, 0),
    // C = (5, -1), D=(5, 9)
    p1.x = 0; p1.y = 9;
    p2.x = -1; p2.y = 0;
    p3.x = 5; p3.y = -1;
    p4.x = 5; p4.y = 9;
    System.out.println(no_of_quads(p1, p2, p3, p4));
  
    // A=(0, 9), B=(-1, 0), 
    // C=(5, -1), D=(0, 3)
    p1.x = 0; p1.y = 9;
    p2.x = -1; p2.y = 0;
    p3.x = 5; p3.y = -1;
    p4.x = 0; p4.y = 3;
    System.out.println(no_of_quads(p1, p2, p3, p4));
  
    // A=(0, 9), B=(0, 10), 
    // C=(0, 11), D=(0, 12)
    p1.x = 0; p1.y = 9;
    p2.x = 0; p2.y = 10;
    p3.x = 0; p3.y = 11;
    p4.x = 0; p4.y = 12;
    System.out.println(no_of_quads(p1, p2, p3, p4));
  
    // A=(0, 9), B=(0, 9),
    // C=(5, -1), D=(0, 3)
    p1.x = 0; p1.y = 9;
    p2.x = 0; p2.y = 9;
    p3.x = 5; p3.y = -1;
    p4.x = 0; p4.y = 3;
    System.out.println(no_of_quads(p1, p2, p3, p4));
}
}
  
// This code is contributed
// by Arnab Kundu


C#
// C# implementation of above approach
using System;
class GFG 
{ 
public class Point // points 
{ 
    public int x; 
    public int y; 
} 
  
// determines the orientation of points 
static int orientation(Point p, Point q, 
                                Point r) 
{ 
    int val = (q.y - p.y) * (r.x - q.x) - 
            (q.x - p.x) * (r.y - q.y); 
  
    if (val == 0) 
        return 0; 
    return (val > 0) ? 1 : 2; 
} 
  
// check whether the distinct 
// line segments intersect 
static bool doIntersect(Point p1, Point q1, 
                        Point p2, Point q2) 
{ 
    int o1 = orientation(p1, q1, p2); 
    int o2 = orientation(p1, q1, q2); 
    int o3 = orientation(p2, q2, p1); 
    int o4 = orientation(p2, q2, q1); 
  
    if (o1 != o2 && o3 != o4) 
        return true; 
  
    return false; 
} 
  
// check if points overlap(similar) 
static bool similar(Point p1, Point p2) 
{ 
  
    // it is same, we are returning 
    // false because quadrilateral is 
    // not possible in this case 
    if (p1.x == p2.x && p1.y == p2.y) 
        return false; 
  
    // it is not same, So there is a 
    // possibility of a quadrilateral 
    return true; 
} 
  
// check for collinearity 
static bool collinear(Point p1, Point p2, 
                        Point p3) 
{ 
    int x1 = p1.x, y1 = p1.y; 
    int x2 = p2.x, y2 = p2.y; 
    int x3 = p3.x, y3 = p3.y; 
  
    // it is collinear, we are returning 
    // false because quadrilateral is not 
    // possible in this case 
    if ((y3 - y2) * 
        (x2 - x1) == (y2 - y1) * 
                    (x3 - x2)) 
        return false; 
  
    // it is not collinear, So there 
    // is a possibility of a quadrilateral 
    else
        return true; 
} 
  
static int no_of_quads(Point p1, Point p2, 
                    Point p3, Point p4) 
{ 
    // Checking for cases where 
    // no quadrilateral = 0 
  
    // check if any of the 
    // points are same 
    bool same = true; 
    same = same & similar(p1, p2); 
    same = same & similar(p1, p3); 
    same = same & similar(p1, p4); 
    same = same & similar(p2, p3); 
    same = same & similar(p2, p4); 
    same = same & similar(p3, p4); 
  
    // similar points exist 
    if (same == false) 
        return 0; 
  
    // check for collinearity 
    bool coll = true; 
    coll = coll & collinear(p1, p2, p3); 
    coll = coll & collinear(p1, p2, p4); 
    coll = coll & collinear(p1, p3, p4); 
    coll = coll & collinear(p2, p3, p4); 
  
    // points are collinear 
    if (coll == false) 
        return 0; 
  
    // Checking for cases where 
    // no of quadrilaterals= 1 or 3 
  
    int check = 0; 
  
    if (doIntersect(p1, p2, p3, p4)) 
        check = 1; 
    if (doIntersect(p1, p3, p2, p4)) 
        check = 1; 
    if (doIntersect(p1, p2, p4, p3)) 
        check = 1; 
  
    if (check == 0) 
        return 3; 
    return 1; 
} 
  
// Driver code 
static void Main() 
{ 
    Point p1, p2, p3, p4; 
    p1 = new Point(); 
    p2 = new Point(); 
    p3 = new Point(); 
    p4 = new Point(); 
      
    // A =(0, 9), B = (-1, 0), 
    // C = (5, -1), D=(5, 9) 
    p1.x = 0; p1.y = 9; 
    p2.x = -1; p2.y = 0; 
    p3.x = 5; p3.y = -1; 
    p4.x = 5; p4.y = 9; 
    Console.WriteLine(no_of_quads(p1, p2, p3, p4)); 
  
    // A=(0, 9), B=(-1, 0), 
    // C=(5, -1), D=(0, 3) 
    p1.x = 0; p1.y = 9; 
    p2.x = -1; p2.y = 0; 
    p3.x = 5; p3.y = -1; 
    p4.x = 0; p4.y = 3; 
    Console.WriteLine(no_of_quads(p1, p2, p3, p4)); 
  
    // A=(0, 9), B=(0, 10), 
    // C=(0, 11), D=(0, 12) 
    p1.x = 0; p1.y = 9; 
    p2.x = 0; p2.y = 10; 
    p3.x = 0; p3.y = 11; 
    p4.x = 0; p4.y = 12; 
    Console.WriteLine(no_of_quads(p1, p2, p3, p4)); 
  
    // A=(0, 9), B=(0, 9), 
    // C=(5, -1), D=(0, 3) 
    p1.x = 0; p1.y = 9; 
    p2.x = 0; p2.y = 9; 
    p3.x = 5; p3.y = -1; 
    p4.x = 0; p4.y = 3; 
    Console.WriteLine(no_of_quads(p1, p2, p3, p4)); 
} 
} 
  
// This code is contributed by mits


输出:
1
3
0
0