25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more...
Home   Projects   Up   Sitemap   Search   Blog   Forum+Chat   About Us   Privacy   Terms of Use   Feedback   FAQ   Images   Services   Payments   Humor   Music

C++ rectangle class that uses doubles for dimensions and calculations

DoubleRect is a C++ class that defines a rectangle but uses doubles instead of integers for dimensions and calculations.

It has functions to return the coordinates of its corners, midpoints of its edges, the smaller rectangles that constitute its own quadrants, and the larger rectangle of which it is the center quadrant.

As one example of its use, a Mandelbrot or similar program can use it to quickly define a region to zoom into or out of.

This version has been tested in Windows with Microsoft Visual C++ and the .NET Framework and in Linux with GNU GCC g++. There is an earlier version for Borland C++ and OWL.

The code below requires the appropriate version of my.h, for Visual C++ or GNU g++.

doubrect.h

/*	doubrect.h		1-25-2010	Microsoft Visual C++ or GNU GCC g++
	Copyright (C)1995-2000, 2006, 2008, 2010 Steven Whitney.
	Initially published by http://25yearsofprogramming.com.
	Published under GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY.

	A rectangle class like Borland TRect (except as noted), but with doubles.
	Points are complex<double>.

To Do:

--Could adapt a number of other TRect functions from point.h and point.cpp


*/
#ifndef __DOUBRECT_H
#define __DOUBRECT_H

#include <complex>

#include "my.h"	// use the my.h version that matches your compiler

using namespace std;

#if defined(WIN32)
	using namespace System::Drawing;
#endif

//////////////////////////////////////////////////////////////////////////////
struct DoubleRect
{
	// default values define the Mandelbrot set: note it's a square region
	DoubleRect(double l = -2, double t = 1.25, double r = .5, double b = -1.25);
	DoubleRect(complex<double> tl, complex<double> br);
	DoubleRect(const DoubleRect& other) { *this = other; }

#if defined(WIN32)
	DoubleRect(System::Drawing::Rectangle^ other);		
#endif

	DoubleRect& operator = (const DoubleRect& other);   	// assignment

	bool operator == (const DoubleRect& other) const;
	bool operator != (const DoubleRect& other) const { return(!(*this == other)); }

	friend ostream& operator << (ostream&, DoubleRect&);  	// put-to operator
	friend istream& operator >> (istream&, DoubleRect&);  	// get-from operator

	// functions
	complex<double> TopLeft();			// the corner points of the rectangle
	complex<double> TopRight();
	complex<double> BottomLeft();
	complex<double> BottomRight();
	complex<double> MidLeft();			// the midpoints of the boundaries
	complex<double> MidTop();
	complex<double> MidRight();
	complex<double> MidBottom();
	complex<double> Center();			// the centerpoint of the rectangle
	double Height();
	double Width();
	double Area();
	void Normalize();      				// ensure top < bottom, left < right
	bool Contains(const DoubleRect& m);	// borders ARE part of the rectangle. true if identical
	bool Contains(complex<double> c);	// also true if lands ON a boundary
	DoubleRect TopLeftQuad();			// calculate quadrants of this DoubleRect
	DoubleRect TopRightQuad();
	DoubleRect BottomLeftQuad();
	DoubleRect BottomRightQuad();
	DoubleRect CenterQuad();
	DoubleRect IsCenterQuadOf();		// (larger) region of which this one is the CenterQuad
	DoubleRect FlippedVertical();
	DoubleRect FlippedHorizontal();

	// variables
	double left;            			// boundaries of the rectangle
	double top;
	double right;
	double bottom;
};

//////////////////////////////////////////////////////////////////////////////
#endif			// __DOUBRECT_H

doubrect.cpp

/*	doubrect.cpp			1-25-2010		Microsoft Visual C++ or GNU GCC g++
	Copyright (C)1995-2000, 2006, 2008, 2010 Steven Whitney.
	Initially published by http://25yearsofprogramming.com.
	Published under GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY.

*/
#include "doubrect.h"

using namespace std;

#if defined(WIN32)
	using namespace System::Drawing;
#endif

//////////////////////////////////////////////////////////////////////////////
// code for class DoubleRect
//----------------------------------------------------------------------------
// constructor
DoubleRect::DoubleRect(double l, double t, double r, double b) :
	left(l), top(t), right(r), bottom(b)
{
	Normalize();
}
//----------------------------------------------------------------------------
// constructor
DoubleRect::DoubleRect(complex<double> tl, complex<double> br) :
	left(real(tl)), top(imag(tl)), right(real(br)), bottom(imag(br))
{
	Normalize();
}
//----------------------------------------------------------------------------
#if defined(WIN32)
DoubleRect::DoubleRect(System::Drawing::Rectangle^ r) :
	left(r->Left), top(r->Top), right(r->Right), bottom(r->Bottom)
{
	Normalize();
}
#endif
//----------------------------------------------------------------------------
bool DoubleRect::operator == (const DoubleRect& other) const
{
DoubleRect a(*this), b(other); 					// the copies are Normalized 
return((a.left == b.left) && (a.top == b.top) && 
		(a.right == b.right) && (a.bottom == b.bottom));
}
//----------------------------------------------------------------------------
// a normal DoubleRect has higher Y value at TOP, UNLIKE a Normalized() TRect.
void DoubleRect::Normalize()
{
	if(left > right) swap(left,right);
	if(bottom > top) swap(bottom,top);
}
//----------------------------------------------------------------------------
double DoubleRect::Height() { Normalize(); return(top - bottom); }
double DoubleRect::Width()  { Normalize(); return(right - left); }
double DoubleRect::Area() 	{ return(Height() * Width()); }
//----------------------------------------------------------------------------
// differs from its TRect counterpart: all borders ARE part of the rectangle
// also true if the two rectangles are identical
bool DoubleRect::Contains(const DoubleRect& m)
{
return((left <= m.left) && (right >= m.right) && (top >= m.top) && (bottom <= m.bottom));
}
//----------------------------------------------------------------------------
// also true if the point lands ON a boundary
bool DoubleRect::Contains(complex<double> c)
{
return((left <= real(c)) && (right >= real(c)) && (top >= imag(c)) && (bottom <= imag(c)));
}
//----------------------------------------------------------------------------
// the corner points of the rectangle
complex<double> DoubleRect::TopLeft()		{ return(complex<double>(left,top)); }
complex<double> DoubleRect::TopRight()	 	{ return(complex<double>(right,top)); }
complex<double> DoubleRect::BottomLeft() 	{ return(complex<double>(left,bottom)); }
complex<double> DoubleRect::BottomRight()	{ return(complex<double>(right,bottom)); }
//----------------------------------------------------------------------------
// the midpoints of the boundaries
complex<double> DoubleRect::MidLeft() 		{ return(complex<double>(left,top - Height() / 2.)); }
complex<double> DoubleRect::MidTop() 		{ return(complex<double>(left + Width() / 2., top)); }
complex<double> DoubleRect::MidRight() 		{ return(complex<double>(right, top - Height() / 2.)); }
complex<double> DoubleRect::MidBottom() 	{ return(complex<double>(left + Width() / 2., bottom)); }
//----------------------------------------------------------------------------
// the centerpoint
complex<double> DoubleRect::Center() { return(complex<double>(left + Width() / 2., top - Height() / 2.)); }
//----------------------------------------------------------------------------
// assignment
DoubleRect& DoubleRect::operator = (const DoubleRect& other)
{
if(&other != this)
{
	left = other.left;
	top = other.top;
	right = other.right;
	bottom = other.bottom;
}
Normalize();
return(*this);
}
//----------------------------------------------------------------------------
// output to any ostream, format: left top right bottom
ostream& operator << (ostream& os, DoubleRect& r)
{
os << setprecision(16) << r.left << " " << setprecision(16) << r.top << " "
   << setprecision(16) << r.right << " " << setprecision(16) << r.bottom;
return os;
}
//----------------------------------------------------------------------------
// input from any istream, format: left top right bottom\n
istream& operator >> (istream& is, DoubleRect& r)
{
is >> r.left >> r.top >> r.right >> r.bottom;
return is;
}
//----------------------------------------------------------------------------
DoubleRect DoubleRect::TopLeftQuad()
{
Normalize();
return DoubleRect(left,top,left + Width()/2.,top - Height()/2.);
}
//----------------------------------------------------------------------------
DoubleRect DoubleRect::TopRightQuad()
{
Normalize();
return DoubleRect(left + Width()/2.,top,right,top - Height()/2.);
}
//----------------------------------------------------------------------------
DoubleRect DoubleRect::BottomLeftQuad()
{
Normalize();
return DoubleRect(left,top - Height()/2.,left + Width()/2.,bottom);
}
//----------------------------------------------------------------------------
DoubleRect DoubleRect::BottomRightQuad()
{
Normalize();
return DoubleRect(left + Width()/2.,top - Height()/2.,right,bottom);
}
//----------------------------------------------------------------------------
DoubleRect DoubleRect::CenterQuad()
{
Normalize();
return DoubleRect(left + Width()/4.,top - Height()/4.,
					right - Width()/4.,bottom + Height()/4.);
}
//----------------------------------------------------------------------------
// returns region of which this one is the CenterQuad (effectively zooms out)
// returned region has 4x the area, enlarged 2x in both directions.
DoubleRect DoubleRect::IsCenterQuadOf()
{
Normalize();
return DoubleRect(left - Width()/2.,top + Height()/2.,
					right + Width()/2.,bottom - Height()/2.);
}
//----------------------------------------------------------------------------
DoubleRect DoubleRect::FlippedVertical()
{
Normalize();
return DoubleRect(left, -bottom, right, -top);
}
//----------------------------------------------------------------------------
DoubleRect DoubleRect::FlippedHorizontal()
{
Normalize();
return DoubleRect(-right, top, -left, bottom);
}
//----------------------------------------------------------------------------
// 						end class DoubleRect
//////////////////////////////////////////////////////////////////////////////

 

Valid HTML 4.01 Transitional Valid CSS
Yahoo! Search
Search the web Search this site
View content labeling at ICRA.