Rectangle Structure - Better method for encapsulation?

The structure below for a Rectangle object works, however I am wondering if there is a better way to go about encapsulating my variables. There are two that are public, point 1 (P1) and point 2 (P2). A "point" is another structure that is basically just an x and y float (think point on a coordinate grid).

I have always been told to make class variables private and don't allow direct access, but I'm not sure if this particular case would warrant it? If I don't want to restrict the variable beyond the natural scope of the two x and y float values of a point structure, is there any reason to encapsulate by making the P1 and P2 private?


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
//Rectangle Structure

#ifndef RECTANGLE_H
#define RECTANGLE_H

#ifndef POINT_H
	#include "point.h"
#endif

struct rectangle{
	point P1;
	point P2;

	rectangle() :P1(point(0,0)), P2(point(0,0)) {};
	rectangle(point p1, point p2) :P1(p1), P2(p2) {};
	rectangle(float X1, float Y1, float X2, float Y2)
	{ P1.X = X1; P1.Y = Y1; P2.X = X2; P2.Y = Y2; };

	int Width() { return int(abs(P2.X - P1.X)+1); }
	int Height() { return int(abs(P2.Y - P1.Y)+1); }
	int Area() { return (Width() * Height()); }

	point UpperLeft();
	point BottomRight();
	point UpperRight();
	point BottomLeft();
	
	bool CollidesWith(rectangle rec);
	bool CollidesWith(point p);
	rectangle OverlapRegion(rectangle rec);

	void Create(point,int,int);

};

point rectangle::UpperLeft()
{
	return point(
		(P1.X < P2.X) ? P1.X : P2.X,
		(P1.Y < P2.Y) ? P1.Y : P2.Y);
}
point rectangle::BottomRight()
{
	return point(
		(P1.X > P2.X) ? P1.X : P2.X,
		(P1.Y > P2.Y) ? P1.Y : P2.Y);
}
point rectangle::UpperRight()
{
	return point(BottomRight().X, UpperLeft().Y);
}
point rectangle::BottomLeft()
{
	return point(UpperLeft().X, BottomRight().Y);
}

bool rectangle::CollidesWith(rectangle rec)
{
	if (UpperLeft().Y > rec.BottomRight().Y) return false;
	if (BottomRight().Y < rec.UpperLeft().Y) return false;
	if (UpperLeft().X > rec.BottomRight().X) return false;
	if (BottomRight().X < rec.UpperLeft().X) return false;
	return true;
}

bool rectangle::CollidesWith(point p)
{
	if (UpperLeft().Y > p.Y) return false;
	if (BottomRight().Y < p.Y) return false;
	if (UpperLeft().X > p.X) return false;
	if (BottomRight().X < p.X) return false;
	return true;
}

rectangle rectangle::OverlapRegion(rectangle rec)
{
	rectangle regionRec(-1,-1,-1,-1);
	if (CollidesWith(rec) == false) return regionRec;
	regionRec.P1.X = ((UpperLeft().X >= rec.UpperLeft().X) ? rec.UpperLeft().X : UpperLeft().X) + abs(UpperLeft().X - rec.UpperLeft().X);
	regionRec.P1.Y = ((UpperLeft().Y >= rec.UpperLeft().Y) ? rec.UpperLeft().Y : UpperLeft().Y) + abs(UpperLeft().Y - rec.UpperLeft().Y);
	regionRec.P2.X = ((BottomRight().X >= rec.BottomRight().X) ? BottomRight().X : rec.BottomRight().X) - abs(BottomRight().X - rec.BottomRight().X);
	regionRec.P2.Y = ((BottomRight().Y >= rec.BottomRight().Y) ? BottomRight().Y : rec.BottomRight().Y) - abs(BottomRight().Y - rec.BottomRight().Y);

	//Swap if P2 is left of P1
	if (P2.X < P1.X)
	{
		point tmpPt = P1;
		P1 = P2;
		P2 = tmpPt;
	}
	return regionRec;
}

void rectangle::Create(point pos, int width, int height)
{
	P1 = pos;
	P2 = point(pos.X + (width-1), pos.Y + (height-1));
}

#endif 
Last edited on
The point structure if for some reason you think it would be helpful to know:

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

#ifndef POINT_H
#define POINT_H

#include <iostream>
#include <math.h>

struct point {
	float X, Y;
	point(float X, float Y) :X(X),Y(Y) {};
	point(float N) :X(N),Y(N) {};
	point() :X(0.0),Y(0.0) {};

	float Slope(point p)
	{
		//Slope = m
		// m = (y2-y1) / (x2-x1)
		float m = ((p.Y-Y) / (p.X-X));
		return m;
	}

	float Distance(point p)
	{
		//Distance = d
		//d = square_root of [ (x2-x1)^2 + (y2-y1)^2 ]
		float d = ((p.X-X) * (p.X-X)) + ((p.Y-Y) * (p.Y-Y));
		d = sqrt(d);
		return d;
	}

	point Increment(point p, float dist)
	{
		//Find a point between this point and point(p), adding a specified distance(dist)
		//New x position = Nx
		//New y position = Ny
		//Nx = X + (dist / square root of [ (m^2 + 1) ])
		//Ny = Y + (m*dist / square root of [ (m^2 + 1) ])
		float m = Slope(p);

		float Nx = dist / (sqrt((m*m) + 1));
		if (m >= 0.0) Nx = ((X < p.X) ? (X+Nx):(p.X+Nx));
		if (m < 0.0) Nx = ((X < p.X) ? (X+Nx):(p.X+Nx));

		float Ny = (m * dist) / (sqrt((m*m) + 1));
		if (m >= 0.0) Ny = ((Y < p.Y) ? (Y+Ny):(p.Y+Ny));
		if (m < 0.0) Ny = ((Y < p.Y) ? (p.Y+Ny):(Y+Ny));

		return point(Nx,Ny);
	}

	float Magnitude()
	{
		//Distance from 0,0 (if point is a vector)
		return Distance(point(0,0));
	}

	point Normalize()
	{
		float nX = (X/Magnitude());
		float nY = (Y/Magnitude());
		return point(nX,nY);
	}
	
	//Addition
	point operator+=(point pnt){ (*this).X += pnt.X; (*this).Y += pnt.Y; return (*this); }
	point operator+=(float num){ (*this).X += num; (*this).Y += num; return (*this); }
	point operator+(point pnt) { return point((*this).X + pnt.X, (*this).Y + pnt.Y);	}
	point operator+(float num) { return point((*this).X + num, (*this).Y + num); }

	//Subtraction
	point operator-=(point pnt){ (*this).X -= pnt.X; (*this).Y -= pnt.Y; return (*this); }
	point operator-=(float num){ (*this).X -= num; (*this).Y -= num; return (*this); }
	point operator-(point pnt) { return point((*this).X - pnt.X, (*this).Y - pnt.Y); }
	point operator-(float num) { return point((*this).X - num, (*this).Y - num); }

  //Multiplication
	point operator*=(point pnt){ (*this).X *= pnt.X; (*this).Y *= pnt.Y; return (*this); }
	point operator*=(float num){ (*this).X *= num; (*this).Y *= num; return (*this); }
	point operator*(point pnt) { return point((*this).X * pnt.X, (*this).Y * pnt.Y); }
	point operator*(float num) { return point((*this).X * num, (*this).Y * num); }

	//Division
	point operator/=(point pnt){ (*this).X /= pnt.X; (*this).Y /= pnt.Y; return (*this); }
	point operator/=(float num){ (*this).X /= num; (*this).Y /= num; return (*this); }
	point operator/(point pnt) { return point((*this).X / pnt.X, (*this).Y / pnt.Y); }
	point operator/(float num) { return point((*this).X / num, (*this).Y / num); }

	//Equal (Assignment)
	point operator=(point pnt) { (*this).X = pnt.X; (*this).Y = pnt.Y; return (*this); }
	point operator=(float num) { (*this).X = num; (*this).Y = num; return (*this); }
};

	bool operator==(point a, point b) { return a.X==b.X && a.Y==b.Y; }
	bool operator==(point a, float num) { return a.X==num && a.Y==num; }

	bool operator!=(point a, point b) { return !(a==b); }
	bool operator!=(point a, float num) { return !(a.X==num && a.Y==num); }

	std::ostream& operator<<(std::ostream& os, const point a)
	{
  os << "(" << a.X << "," << a.Y << ")";
  return os;
	}

#endif
Topic archived. No new replies allowed.