|
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 calculationsDoubleRect 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 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 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
//////////////////////////////////////////////////////////////////////////////
|
|
|
|