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   Ads   Donate   Humor

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

DoubleRect is a C++ class that defines a rectangle but uses doubles 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 an example of its use, a Mandelbrot or similar program can use it to quickly define a region to be zoomed into or back out of.

This version is for Microsoft Visual C++ and the .NET Framework.

It requires my.h.

doubrect.h

/*	doubrect.h			6-26-2008		MSVC++
	Copyright (C)1995-2000, 2006, 2008 Steven Whitney.
	Initially published by http://25yearsofprogramming.com.
	Published under GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY.

	like TRect (except as noted), but with doubles.
	can hold coordinates for a region of the Mandelbrot set;
	points within the set are complex instead of TPoint because TPoint only uses ints.

------
To Do:

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

------
Notes:
--One function, which uses TRect, is unavailable when using this class under MSDOS.

*/
#ifndef __DOUBRECT_H
#define __DOUBRECT_H

#include <complex>
#if defined(_Windows)
	#include <owl\point.h>
#endif

#include "my.h"

using namespace std;
using namespace System::Drawing;

//////////////////////////////////////////////////////////////////////////////
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; }
	DoubleRect(System::Drawing::Rectangle^ other);		

	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      	6-26-2008		MSVC++
	Copyright (C)1995-2000, 2006, 2008 Steven Whitney.
	Initially published by http://25yearsofprogramming.com.
	Published under GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY.

	like TRect (except as noted), but with doubles.
	can hold coordinates for a region of the Mandelbrot set;
	points within the set are complex instead of TPoint because TPoint only uses ints.

*/
#include "doubrect.h"

using namespace std;
using namespace System::Drawing;

//////////////////////////////////////////////////////////////////////////////
// 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();
}
//----------------------------------------------------------------------------
DoubleRect::DoubleRect(System::Drawing::Rectangle^ r) :
	left(r->Left), top(r->Top), right(r->Right), bottom(r->Bottom)
{
	Normalize();
}
//----------------------------------------------------------------------------
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
View content labeling at ICRA.
Copyright ©2008 Steven Whitney. Last modified 07/26/2008.