1. Homepage of Dr. Zoltán Porkoláb
    1. Home
    2. Archive
  2. Teaching
    1. Timetable
    2. Bolyai College
    3. C++ (for mathematicians)
    4. Imperative programming (BSc)
    5. Multiparadigm programming (MSc)
    6. Programming (MSc Aut. Sys.)
    7. Programming languages (PhD)
    8. Software technology lab
    9. Theses proposals (BSc and MSc)
  3. Research
    1. Sustrainability
    2. CodeChecker
    3. CodeCompass
    4. Templight
    5. Projects
    6. Conferences
    7. Publications
    8. PhD students
  4. Affiliations
    1. Dept. of Programming Languages and Compilers
    2. Ericsson Hungary Ltd

Practice 8.

Points and rectangles

Write a program which represents rectangles using points.
Create functions to compute the area and the periphery of the rectangle, and functions to decide whether a point is inside or on the rectangle, and one more to decide whether the rectangle is a square.

Solution

Video:

cpp-mat-gyak8_rectangle.mp4

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <iostream>
#include <cmath>
#include <ios>
#include <vector>
#include <cassert>

struct Point  // representing a point 
{
  double x;
  double y;
};

struct Rectangle  // representing s rectangle
{
  Point leftLower;   // with two points: the left lower
  Point rightUpper;  //             and the right upper
	
  Rectangle(Point ll, Point ru)  // constructor
  {
    assert(ll.x < ru.x);   // check, that the parameters
    assert(ll.y < ru.y);   // are valid, otherwise abort 
	
    leftLower = ll;        // set the attributes
    rightUpper = ru;
  }
};

double pointDistance(const Point& p, const Point& r);
Point rightLower(const Rectangle& r);

double area(const Rectangle& r);
double periphery(const Rectangle& r);

bool isSquare(const Rectangle& r);
bool isInnerPoint(const Rectangle& r, const Point& p);
bool isPointOnSide(const Rectangle& r, const Point& p);

int main()
{
  Point p = { 3, 2 };   // aggregate initialization
  Point q;              // no initialization
  q.x = 9;
  q.y = 7;
	
  Rectangle rect = { { 3, 2 }, { 9 , 7 } };

  // this is also a proper constructor call
  Rectangle rect2( { 3, 4 }, { 6 , 7 } ); 

  std::cout << pointDistance(p, q) << std::endl;
  std::cout << "Area of the rectangle is: " 
	    << area(rect) << std::endl;
  std::cout << "Periphery of the rectangle is: " 
	    << periphery(rect) << std::endl;
	
  std::cout << std::boolalpha << isSquare(rect)
                              << std::endl;  
  // std::noboolalpha to disable bool to string conversion
  std::cout << isSquare(rect2) << std::endl;
  std::cout << isInnerPoint(rect, Point{6, 4})
                              << std::endl;
  std::cout << isInnerPoint(rect, Point{-5, -2})
                              << std::endl;
	
  srand(time(0)); // seed: "randomize" the random generator
  std::vector<Point> points;
  for (int i = 0; i < 10; ++i)
  {
    // generate random points  
    points.push_back(Point{(double)(rand() % 10), 
                           (double)(rand() % 10)});
    std::cout << "(" << points[i].x << ", " 
                     << points[i].y << ") ";
		
    if (isInnerPoint(rect, points[i]))
    {
      std::cout << "is inside the rectangle.\n";
    }
    else if (isPointOnSide(rect, points[i]))
    {
      std::cout << "is on the rectangle.\n";
    }
    else
    {
      std::cout << "is outside the rectangle.\n";
    }
  }
}

double area(const Rectangle& r)
{
  Point rightLowerPoint = rightLower(r);
  double a = pointDistance(rightLowerPoint, r.leftLower);
  double b = pointDistance(r.rightUpper, rightLowerPoint);
  return a * b;
}

double periphery(const Rectangle& r)
{
  Point rightLowerPoint = rightLower(r);
  double a = pointDistance(rightLowerPoint, r.leftLower);
  double b = pointDistance(r.rightUpper, rightLowerPoint);
  return 2 * a + 2 * b;
}

bool isSquare(const Rectangle& r)
{
  if (std::abs(r.leftLower.x - r.rightUpper.x) ==
      std::abs(r.leftLower.y - r.rightUpper.y))
  {
    return true;
  }
  return false;
}

bool isInnerPoint(const Rectangle& r, const Point& p)
{
  if (p.x < r.rightUpper.x  &&  p.x > r.leftLower.x &&
      p.y < r.rightUpper.y  &&  p.y > r.leftLower.y)
  {
    return true;
  }
  return false;
}

bool isPointOnSide(const Rectangle& r, const Point& p)
{
  if ((p.x == r.leftLower.x || p.x == r.rightUpper.x) &&
         p.y > r.leftLower.y && p.y < r.rightUpper.y ||
      (p.y == r.leftLower.y || p.y == r.rightUpper.y) &&
       p.x > r.leftLower.x && p.x < r.rightUpper.x)
  {
    return true;
  }
  return false;
}

double pointDistance(const Point& p, const Point& r)
{
  return std::sqrt(std::pow(p.x - r.x, 2.0) 
		   + std::pow(p.y - r.y, 2.0));
}

Point rightLower(const Rectangle& r)
{
  double x = r.rightUpper.x;
  double y = r.leftLower.y;
  return Point{ x, y };  // temporary object
}

The expected output:

$ ./a.out 
7.81025
Area of the rectangle is: 30
Periphery of the rectangle is: 22
false
true
true
false
(4, 2) is on the rectangle.
(8, 6) is inside the rectangle.
(2, 9) is outside the rectangle.
(3, 8) is outside the rectangle.
(5, 3) is inside the rectangle.
(2, 2) is outside the rectangle.
(8, 1) is outside the rectangle.
(7, 8) is outside the rectangle.
(1, 2) is outside the rectangle.
(4, 4) is inside the rectangle.
Financed from the financial support ELTE won from the Higher Education Restructuring Fund of the Hungarian Government.