Open In App

Check if four segments form a rectangle

We are given four segments as a pair of coordinates of their end points. We need to tell whether those four line segments make a rectangle or not. 
Examples: 
 

Input : segments[] =  [(4, 2), (7, 5),
                       (2, 4), (4, 2),
                       (2, 4), (5, 7),
                       (5, 7), (7, 5)]
Output : Yes
Given these segment make a rectangle of length 3X2.

Input : segment[] = [(7, 0), (10, 0),
                     (7, 0), (7, 3),
                     (7, 3), (10, 2),
                     (10, 2), (10, 0)]
Output : Not
These segments do not make a rectangle.

Above examples are shown in below diagram.

This problem is mainly an extension of How to check if given four points form a square
 

We can solve this problem by using properties of a rectangle. First, we check total unique end points of segments, if count of these points is not equal to 4 then the line segment can’t make a rectangle. Then we check distances between all pair of points, there should be at most 3 different distances, one for diagonal and two for sides and at the end we will check the relation among these three distances, for line segments to make a rectangle these distance should satisfy Pythagorean relation because sides and diagonal of rectangle makes a right angle triangle. If they satisfy mentioned conditions then we will flag polygon made by line segment as rectangle otherwise not.
 




// C++ program to check whether it is possible
// to make a rectangle from 4 segments
#include <bits/stdc++.h>
using namespace std;
#define N 4
 
// structure to represent a segment
struct Segment
{
    int ax, ay;
    int bx, by;
};
 
// Utility method to return square of distance
// between two points
int getDis(pair<int, int> a, pair<int, int> b)
{
    return (a.first - b.first)*(a.first - b.first) +
        (a.second - b.second)*(a.second - b.second);
}
 
// method returns true if line Segments make
// a rectangle
bool isPossibleRectangle(Segment segments[])
{
    set< pair<int, int> > st;
 
    // putting all end points in a set to
    // count total unique points
    for (int i = 0; i < N; i++)
    {
        st.insert(make_pair(segments[i].ax, segments[i].ay));
        st.insert(make_pair(segments[i].bx, segments[i].by));
    }
 
    // If total unique points are not 4, then
    // they can't make a rectangle
    if (st.size() != 4)
        return false;
 
    // dist will store unique 'square of distances'
    set<int> dist;
 
    // calculating distance between all pair of
    // end points of line segments
    for (auto it1=st.begin(); it1!=st.end(); it1++)
        for (auto it2=st.begin(); it2!=st.end(); it2++)
            if (*it1 != *it2)
                dist.insert(getDis(*it1, *it2));
 
    // if total unique distance are more than 3,
    // then line segment can't make a rectangle
    if (dist.size() > 3)
        return false;
 
    // copying distance into array. Note that set maintains
    // sorted order.
    int distance[3];
    int i = 0;
    for (auto it = dist.begin(); it != dist.end(); it++)
        distance[i++] = *it;
 
    // If line seqments form a square
    if (dist.size() == 2)
    return (2*distance[0] == distance[1]);
 
    // distance of sides should satisfy pythagorean
    // theorem
    return (distance[0] + distance[1] == distance[2]);
}
 
// Driver code to test above methods
int main()
{
    Segment segments[] =
    {
        {4, 2, 7, 5},
        {2, 4, 4, 2},
        {2, 4, 5, 7},
        {5, 7, 7, 5}
    };
 
    (isPossibleRectangle(segments))?cout << "Yes\n":cout << "No\n";
}




/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
 
// java program to check whether it is possible
// to make a rectangle from 4 segments
public class Main {
  static int N = 4;
 
  // Utility method to return square of distance
  // between two points
  public static int getDis(String a, String b)
  {
    String[] a1 = a.split(",");
    String[] b1 = b.split(",");
    return (Integer.parseInt(a1[0]) - Integer.parseInt(b1[0]))*(Integer.parseInt(a1[0]) - Integer.parseInt(b1[0])) + (Integer.parseInt(a1[1]) - Integer.parseInt(b1[1]))*(Integer.parseInt(a1[1]) - Integer.parseInt(b1[1]));
  }
 
  // method returns true if line Segments make
  // a rectangle
  public static boolean isPossibleRectangle(int[][] segments)
  {
    HashSet<String> st = new HashSet<>();
 
    // putting all end points in a set to
    // count total unique points
    for (int i = 0; i < N; i++)
    {
      st.add(segments[i][0] + "," + segments[i][1]);
      st.add(segments[i][2] + "," + segments[i][3]);
    }
 
    // If total unique points are not 4, then
    // they can't make a rectangle
    if (st.size() != 4)
      return false;
 
    // dist will store unique 'square of distances'
    HashSet<Integer> dist = new HashSet<>();
 
    // calculating distance between all pair of
    // end points of line segments
    for(String it1 : st){
      for(String it2 : st){
        if(it1 != it2){
          dist.add(getDis(it1, it2));
        }
      }
    }
 
    // if total unique distance are more than 3,
    // then line segment can't make a rectangle
    if (dist.size() > 3)
      return false;
 
    // copying distance into array. Note that set maintains
    // sorted order.
    int[] distance = new int[3];
    int i = 0;
    for(int it: dist){
      distance[i] = it;
      i = i + 1;
    }
 
    // If line seqments form a square
    if (dist.size() == 2)
      return (2*distance[0] == distance[1]);
 
    // distance of sides should satisfy pythagorean
    // theorem
    return (distance[0] + distance[1] == distance[2]);
  }
 
 
  public static void main(String[] args) {
    int[][] segments =
    {
      {4, 2, 7, 5},
      {2, 4, 4, 2},
      {2, 4, 5, 7},
      {5, 7, 7, 5}
    };
 
    if(isPossibleRectangle(segments) == true){
      System.out.println("Yes");
    }
    else{
      System.out.println("No");
    }
  }
}
 
// The code is contributed by Nidhi goel.




# Python program to check whether it is possible
# to make a rectangle from 4 segments
N = 4
 
# Utility method to return square of distance
# between two points
def getDis(a, b):
    return (a[0] - b[0])*(a[0] - b[0]) + (a[1] - b[1])*(a[1] - b[1])
 
# method returns true if line Segments make
# a rectangle
def isPossibleRectangle(segments):
 
    st = set()
 
    # putting all end points in a set to
    # count total unique points
    for i in range(N):
        st.add((segments[i][0], segments[i][1]))
        st.add((segments[i][2], segments[i][3]))
 
         
    # If total unique points are not 4, then
    # they can't make a rectangle
    if len(st) != 4:
        return False
 
    # dist will store unique 'square of distances'
    dist = set()
 
    # calculating distance between all pair of
    # end points of line segments
    for it1 in st:
        for it2 in st:
            if it1 != it2:
                dist.add(getDis(it1, it2))
 
    # if total unique distance are more than 3,
    # then line segment can't make a rectangle
    if len(dist) > 3:
        return False
 
    # copying distance into array. Note that set maintains
    # sorted order.
    distance = []
    for x in dist:
        distance.append(x)
     
    # Sort the distance list, as set in python, does not sort the elements by default.
    distance.sort()
     
    # If line seqments form a square
    if len(dist) ==2 :
        return (2*distance[0] == distance[1])
 
    # distance of sides should satisfy pythagorean
    # theorem
    return (distance[0] + distance[1] == distance[2])
 
# Driver code to test above methods
segments = [
        [4, 2, 7, 5],
        [2, 4, 4, 2],
        [2, 4, 5, 7],
        [5, 7, 7, 5]
]
 
if(isPossibleRectangle(segments) == True):
    print("Yes")
else:
    print("No")
     
# The code is contributed by Nidhi goel.




// C# program to check whether it is possible
// to make a rectangle from 4 segments
using System;
using System.Collections.Generic;
 
class GFG {
 
  public static int N = 4;
 
  // Utility method to return square of distance
  // between two points
  public static int getDis(KeyValuePair<int,int> a, KeyValuePair<int,int> b)
  {
    return (a.Key - b.Key)*(a.Key - b.Key) +
      (a.Value - b.Value)*(a.Value - b.Value);
  }
 
  // method returns true if line Segments make
  // a rectangle
  public static bool isPossibleRectangle(int[,] segments)
  {
    HashSet<KeyValuePair<int, int>> st = new HashSet<KeyValuePair<int, int>>();
 
    // putting all end points in a set to
    // count total unique points
    for (int j = 0; j < N; j++)
    {
      st.Add(new KeyValuePair<int, int>(segments[j,0], segments[j,1]));
      st.Add(new KeyValuePair<int, int>(segments[j,2], segments[j,3]));
    }
 
    // If total unique points are not 4, then
    // they can't make a rectangle
    if (st.Count != 4)
      return false;
 
    // dist will store unique 'square of distances'
    HashSet<int> dist = new HashSet<int>();
 
 
    // calculating distance between all pair of
    // end points of line segments
    foreach(var it1 in st){
      foreach(var it2 in st){
        if(it1.Key != it2.Key && it1.Value != it2.Value){
          dist.Add(getDis(it1, it2));
        }
      }
    }
 
    // if total unique distance are more than 3,
    // then line segment can't make a rectangle
    if (dist.Count > 3)
      return false;
 
    // copying distance into array. Note that set maintains
    // sorted order.
    int[] distance = new int[3];
    int i = 0;
    foreach(var it in dist){
      distance[i] = it;
      i = i + 1;
    }
 
    // If line seqments form a square
    if (dist.Count == 2)
      return (2*distance[0] == distance[1]);
 
    // distance of sides should satisfy pythagorean
    // theorem
    return (distance[0] + distance[1] == distance[2]);
  }
 
 
  // Driver code
  public static void Main()
  {
 
    int[,] segments = {
      {4, 2, 7, 5},
      {2, 4, 4, 2},
      {2, 4, 5, 7},
      {5, 7, 7, 5}
    };
 
    if(isPossibleRectangle(segments) == true){
      Console.WriteLine("Yes");
    }
    else{
      Console.WriteLine("No");
    }
  }
}
 
// The code is contributed by Nidhi goel.




// JavaScript program to check whether it is possible
// to make a rectangle from 4 segments
 
const N = 4;
 
// Utility method to return square of distance
// between two points
function getDis(a, b)
{
    return (parseInt(a[0]) - parseInt(b[0]))*(parseInt(a[0]) - parseInt(b[0])) + (parseInt(a[1]) - parseInt(b[1]))*(parseInt(a[1]) - parseInt(b[1]));
}
 
// method returns true if line Segments make
// a rectangle
function isPossibleRectangle(segments)
{  
    let st = new Set();
 
    // putting all end points in a set to
    // count total unique points
    for (let i = 0; i < N; i++)
    {
        let tmp1 = [segments[i][0], segments[i][1]];
        let tmp2 = [segments[i][2], segments[i][3]];
        st.add(tmp1.join(''));
        st.add(tmp2.join(''));
    }
 
    // If total unique points are not 4, then
    // they can't make a rectangle
    if (st.size != 4)
    {
        return false;
    }
         
    // dist will store unique 'square of distances'
    let dist = new Set();
 
    // calculating distance between all pair of
    // end points of line segments
    for(let it1 of st)
    {
        for(let it2 of st)
        {
            if(it1 !== it2)
            {
                dist.add(getDis(it1.split(''), it2.split('')));
            }
        }
    }
 
    // if total unique distance are more than 3,
    // then line segment can't make a rectangle
    if (dist.size > 3)
    {
        return false;
    }
         
    // copying distance into array. Note that set maintains
    // sorted order.
    let distance = new Array();
    for (let x of dist)
    {
        distance.push(x);
    }
         
    // If line seqments form a square
    if (dist.size === 2)
    {
        return (2*distance[0] == distance[1]);
    }
 
    // distance of sides should satisfy pythagorean
    // theorem
    return (distance[0] + distance[1] == distance[2]);
}
 
// Driver code to test above methods
{
    let segments = [
        [4, 2, 7, 5],
        [2, 4, 4, 2],
        [2, 4, 5, 7],
        [5, 7, 7, 5] ]
 
    if(isPossibleRectangle(segments)){
        console.log("Yes");
    }
    else{
        console.log("No");
    }
}
 
// The code is contributed by  Nidhi Goel

Output: 
 

Yes

Time Complexity: O(n2logn) 
Auxiliary Space: O(n)

 


Article Tags :