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.
CPP
#include <bits/stdc++.h>
using namespace std;
#define N 4
struct Segment
{
int ax, ay;
int bx, by;
};
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);
}
bool isPossibleRectangle(Segment segments[])
{
set< pair< int , int > > st;
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 (st.size() != 4)
return false ;
set< int > dist;
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 (dist.size() > 3)
return false ;
int distance[3];
int i = 0;
for ( auto it = dist.begin(); it != dist.end(); it++)
distance[i++] = *it;
if (dist.size() == 2)
return (2*distance[0] == distance[1]);
return (distance[0] + distance[1] == distance[2]);
}
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" ;
}
|
Java
import java.io.*;
import java.util.*;
public class Main {
static int N = 4 ;
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 ]));
}
public static boolean isPossibleRectangle( int [][] segments)
{
HashSet<String> st = new HashSet<>();
for ( int i = 0 ; i < N; i++)
{
st.add(segments[i][ 0 ] + "," + segments[i][ 1 ]);
st.add(segments[i][ 2 ] + "," + segments[i][ 3 ]);
}
if (st.size() != 4 )
return false ;
HashSet<Integer> dist = new HashSet<>();
for (String it1 : st){
for (String it2 : st){
if (it1 != it2){
dist.add(getDis(it1, it2));
}
}
}
if (dist.size() > 3 )
return false ;
int [] distance = new int [ 3 ];
int i = 0 ;
for ( int it: dist){
distance[i] = it;
i = i + 1 ;
}
if (dist.size() == 2 )
return ( 2 *distance[ 0 ] == distance[ 1 ]);
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" );
}
}
}
|
Python3
N = 4
def getDis(a, b):
return (a[ 0 ] - b[ 0 ]) * (a[ 0 ] - b[ 0 ]) + (a[ 1 ] - b[ 1 ]) * (a[ 1 ] - b[ 1 ])
def isPossibleRectangle(segments):
st = set ()
for i in range (N):
st.add((segments[i][ 0 ], segments[i][ 1 ]))
st.add((segments[i][ 2 ], segments[i][ 3 ]))
if len (st) ! = 4 :
return False
dist = set ()
for it1 in st:
for it2 in st:
if it1 ! = it2:
dist.add(getDis(it1, it2))
if len (dist) > 3 :
return False
distance = []
for x in dist:
distance.append(x)
distance.sort()
if len (dist) = = 2 :
return ( 2 * distance[ 0 ] = = distance[ 1 ])
return (distance[ 0 ] + distance[ 1 ] = = distance[ 2 ])
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" )
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static int N = 4;
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);
}
public static bool isPossibleRectangle( int [,] segments)
{
HashSet<KeyValuePair< int , int >> st = new HashSet<KeyValuePair< int , int >>();
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 (st.Count != 4)
return false ;
HashSet< int > dist = new HashSet< int >();
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 (dist.Count > 3)
return false ;
int [] distance = new int [3];
int i = 0;
foreach ( var it in dist){
distance[i] = it;
i = i + 1;
}
if (dist.Count == 2)
return (2*distance[0] == distance[1]);
return (distance[0] + distance[1] == distance[2]);
}
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" );
}
}
}
|
Javascript
const N = 4;
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]));
}
function isPossibleRectangle(segments)
{
let st = new Set();
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 (st.size != 4)
{
return false ;
}
let dist = new Set();
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 ;
}
let distance = new Array();
for (let x of dist)
{
distance.push(x);
}
if (dist.size === 2)
{
return (2*distance[0] == distance[1]);
}
return (distance[0] + distance[1] == distance[2]);
}
{
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" );
}
}
|
Output:
Yes
Time Complexity: O(n2logn)
Auxiliary Space: O(n)
This article is contributed by Aarti_Rathi and Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.