Quadralateral

Hey guys, I'm new to C++ and have a problem here. My code is below, it is just in a separate class so the main is in another. I need to finish my two 'isRectangle' and 'isSquare' statements, to determine whether or not the quadrilateral is a rectangle or square. I just dont know about how to go about doing it, so any help is appreciated. I know its along the lines of if all sides are equal for the square, but i am completely lost on the rectangle. Would it be two sides equal? How would the code look?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  #include "Quadralateral.h"


Quadralateral::Quadralateral(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
  X1 = x1;	// memberwise assignment
  Y1 = y1;
  X2 = x2;
  Y2 = y2;
  X3 = x3;
  Y3 = y3;
  X4 = x4;
  Y4 = y4;
}

bool Quadralateral::isRectangle()
{
// Code help
}

bool Quadralateral::isSquare()
{
// Code help
}

Quadralateral::~Quadralateral(void)
{
}
I'm assuming x1,y1 - x4,y4 are are Cartesian coordinates (you don't specify).

So what the definition of a rectangle?
- sides 1 and 3 the same length and sides 2 and 4 the same length.
- And the corners are 90 degrees.
So your task is to compute the length of each of the four sides, then test the respective lengths.

You don't need to compute the angle of the corners to confirm right angles. Just check that the coordinates of the corners align. i.e. x1 == x3, y1 == y2, etc.

Same for isSquare except all sides must be the same length

Your question is about math.
https://en.wikipedia.org/wiki/Quadrilateral
Rhombus has all sides equal too. Square is a Rectangle.


I do suggest that you create class Point for storing coordinates of one vertex. Then you can implement math for Points. That will simplify and clarify the implementation of your Quadralateral.


@AbstractionAnon: Your x1==x3 is true only for "non-rotated" case.
Last edited on
Well here is my header file which stores the values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
class Quadralateral
{
public:
	Quadralateral(int=0,int=0,int=1,int=0,int=1,int=1,int=0,int=1);
	bool isRectangle();
	bool isSquare();

	~Quadralateral(void);
private:
	int X1,Y1,X2,Y2,X3,Y3,X4,Y4;
};



And and thank you Abstract and keskiverto, so would it look something along the lines of this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "Quadralateral.h"


Quadralateral::Quadralateral(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
  X1 = x1;	// memberwise assignment
  Y1 = y1;
  X2 = x2;
  Y2 = y2;
  X3 = x3;
  Y3 = y3;
  X4 = x4;
  Y4 = y4;
}

bool Quadralateral::isRectangle()
{
x1 == x3 && y1 == y2
}

bool Quadralateral::isSquare()
{
x1 == x3 == y1 == y2
}

Quadralateral::~Quadralateral(void)
{
}

Last edited on
Line 18, 23: Those are not valid statements.

As I pointed out above, there are two parts to checking for a rectangle or square. You're not checking the length of the sides.

And as keskiverto noted above, the example I gave you does not consider rotations. i.e. what if x1,y1 is not the upper left corner.

Last edited on
Ah I understand what you're saying. I just don't have any idea on how to program that! What would the code for lines 18 and 23 look like? I'm sorry, as you can tell I'm new :(
Create a class Point as has been suggested already. Store the 4 points in an array.

Then sort the array. I suggest that points sort by x value, then use y value to break ties.

Now for unrotated points, the problem is easy: For a rectangle points 0 and 1 have the same X coordinate, as do points 2 and 3. Also points 0 and 2 have the same Y coordinate as do points 1 and 3.

A shape is a square if it's a rectangle, and two adjacent sides have the same length.

Once you get this working, you can consider detecting rotated squares and rectangles.
I'm not going to write the whole thing for you, but this should give you a start.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool Quadralateral::isRectangle()
{ int s1;  // side 1 (top)
   int s4;  // size 4 (bottom)
  if (x1 != x3)
    return false;   // Left side is not vertical
  if (y1 != y2)
    return false;  // Top is not horizontal
  s1 = x2 - x1;  // Compute length of top  
  s4 = x4 - x3;  // Compute length of bottom
  if (s1 != s4)
    return false;  // Top and bottom are different lengths
  // Test sides
  return true;  // All tests for a rectangle passed
}


The math is the key. What are the concepts that we are dealing with?
That is what we have to understand first.
When we know that, then we can start to think about possible language syntax.

Some (pseudo)code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Point {
  // code
};

using V = Point; // V for Vertex.

class Quadralateral {
public:
  Quadralateral( V v1, V v2, V v3, V v4 );
  // The v1-4 are the four vertices of the quadrilateral.  They are in order so that
  // The four edges of the quadrilateral are:
  // edgeA == between v1 and v2
  // edgeB == between v2 and v3
  // edgeC == between v3 and v4
  // edgeD == between v4 and v1
  // The two diagonals of the quadrilateral are:
  // diagA == between v1 and v3
  // diagB == between v2 and v4
}

When you consider edge (side) in your assignment, it is enough to know its length, i.e. the distance between the end-points (vertices).

It is good to encapsulate that separately into a function:
double distance( V a, V b );
(Even though coordinates are given as integers, the distances are probably not integers.)

That, however, leads to an unexpected "feature". Equality comparison between double values is non-trivial. See
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/


There is an another, integral way though. That involves (mathematical) vector calculations.

We need two parallel sides in squares and rectangles.
Let v12 be a vector from v1 to v2.
Let v43 be a vector from v4 to v3.
If v12 == v43, then they are parallel and equally long.
Same treatment for the other two edges.

The diagonals are not parallel. Now that I think of it, Pythagora's theorem without calculating square roots can keep you in integers too.
Ok i got you now, Abstract. Here is what i came up with for rectangle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
bool Quadralateral::isRectangle()
{
	int s1; // top
	int s2; // left
	int s3; // right
	int s4; // bottom

  if (X1 != X3)
    return false;   
  if (Y1 != Y2)
    return false;  
	s1 = X2 - X1;    
	s4 = X4 - X3;  
  if (s1 != s4)
    return false;
	s2 = X1 - X3;
	s3 = X2 - X4;
  if (s2 != s3)
    return false;

  if ((s2 = s3) && (s1 = s4))
	  return true;  
  
  
  // All tests for a rectangle passed
}


Is that seem like it'll work correctly, and as for square, that should be simple just checking distance between all sides and then making sure they are even right?


And im sorry keskiverto, that is way over my head haha :D
It is still not working correctly abstract. What am I doing wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

#include "Quadralateral.h"


Quadralateral::Quadralateral(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
  X1 = x1;	// memberwise assignment
  Y1 = y1;
  X2 = x2;
  Y2 = y2;
  X3 = x3;
  Y3 = y3;
  X4 = x4;
  Y4 = y4;
}

bool Quadralateral::isRectangle()
{
	int s1; // top
	int s2; // left
	int s3; // right
	int s4; // bottom

  if (X1 != X3)
    return false;   
  if (Y1 != Y2)
    return false;  
	s1 = X2 - X1;    
	s4 = X4 - X3;  
  if (s1 != s4)
    return false;
	s2 = X1 - X3;
	s3 = X2 - X4;
  if (s2 != s3)
    return false;

  if ((s2 == s3) && (s1 == s4))
	  return true;  
  
  
  // All tests for a rectangle passed
}

bool Quadralateral::isSquare()
{
	int s1; // top
	int s2; // left
	int s3; // right
	int s4; // bottom

  if (X1 != X3)
    return false;   
  if (Y1 != Y2)
    return false;  
	s1 = X2 - X1;    
	s4 = X4 - X3;  
  if (s1 != s4)
    return false;
	s2 = X1 - X3;
	s3 = X2 - X4;
  if (s2 != s3)
    return false;

  if (s2 == s3 == s1 == s4)
	  return true;
 
  // Test for square passed
}

Quadralateral::~Quadralateral(void)
{

}

Line 64 has error. So do the computation of left and right.

Btw, what is the convention of the order of the vertices?
The user must give the vertices, so the user must be told.
The variable names [XY][1234] do not explain much.

(The order can be random, if the object sorts them to its internal convention. Yours doesn't.)


Quiz: What shapes are these:
1
2
3
Quadralateral foo( 0, 0, 1, 1, 1, 0, 2, 1 );
Quadralateral bar( 1, 0, 0, 1, 2, 0, 2, 1 );
Quadralateral gaz( 1, 0, 0, 1, 2, 1, 1, 2 );

Last edited on
isSquare() should call isRectangle(). There's no need to duplicate the code. A square is a rectangle where adjacent sides are the same length.
keskivert, how are my computations wrong? And what did I do wrong on line 64? It is just saying if all sides are equal to each other, then return true, right? I'm new to programming, sorry. The order should be x1,y1 x2,y2 x3,y3 x4,y4, and the corresponding numbers.


The first shape((0,0) (1,1) (1,0) (2,1)) is a rhombus/parallelogram
Second looks like more of a trapezoid
Third is a square
what did I do wrong on line 64? It is just saying if all sides are equal to each other, then return true, right?

No. The if (s2 == s3 == s1 == s4)
is equivalent to
1
2
3
bool t1 = (s2 == s3);
bool t2 = (t1 == s1); // when is int equal to true/false?
if ((t2 == s4)


The order should be x1,y1 x2,y2 x3,y3 x4,y4

What does that mean?
The code sample of AbstractionAnon seems to assume that:
* (x1,y1) is upper left vertex
* (x2,y2) is upper right vertex
* (x3,y3) is lower left vertex
* (x4,y4) is lower right vertex

When I did create the three example Quadralaterals, I did not follow that convention (by mistake).
More descriptive parameter names would make the purpose of each argument more clear.

The order is crucial, if your calculations involve directionality (as they do). x1-x2 != x2-x1

Third is a square

Indeed. However, X1(1) != X3(2) and Y1(0) != Y2(1) so in your class it is not a square.

how are my computations wrong?

The code of AbstractionAnon had comments, explaining each operation. It did compare the lengths of top and bottom horizontal sides.
What was left to you? The lengths of left and right vertical sides.
(We follow the convention that x-axis is horizontal and y-axis is vertical.)
Do you calculate the left and right using the vertical component of the coordinates?
Using different component than for the top and bottom?
No, you don't. You do use only the x-values.
Topic archived. No new replies allowed.