//------------------------------------------- // Filename : Quadrilateral.C // Author : DL Frey // Date : 2/20/03 // Project : CMSC 202 Spring 2003 Project 2 // Section : 1234 // SSN : xxx-xx-1234 // // This file provides the implementation for // the Quadrilateral class required for project 2 // The Quadrilateral uses Point objects to store // x- and y-coordinates of it's corners // // Per the project specification, the implementation // of this class assumes // 1. the base (m_lowerLeft to m_lowerLeft) is parallel to the x-axis // 2. for trapezoids, the parallel sides are also // paralled to one of the axes //----------------------------------------------------------- // Notes to the student // 1. default constructor // the compiler will automatically call the default // constructor for each Point, which will set the // x- and y-coordinates of each point to (0, 0) // 2. mutators // mutators use Point's assigment operator so there // is no need to assign the x- and y-coordinates separately //------------------------------------------------------------- #include "Quadrilateral.H" #include "Point.H" using namespace std; // Default constructor Quadrilateral::Quadrilateral ( void ) { // no code } // mutator for UpperLeft corner void Quadrilateral::SetUpperLeft (const Point& p) { m_upperLeft = p; } // mutator for UpperRight corner void Quadrilateral::SetUpperRight (const Point& p) { m_upperRight = p; } // mutator for LowerRight corner void Quadrilateral::SetLowerRight (const Point& p) { m_lowerRight = p; } // mutator for LowerLeft corner void Quadrilateral::SetLowerLeft (const Point& p) { m_lowerLeft = p; } // accessor for UpperLeft corner const Point& Quadrilateral::GetUpperLeft ( void ) const { return m_upperLeft; } // accessor for LowerLeft corner const Point& Quadrilateral::GetLowerLeft ( void ) const { return m_lowerLeft; } // accessor for UpperRight corner const Point& Quadrilateral::GetUpperRight ( void ) const { return m_upperRight; } // accessor for LowerRight corner const Point& Quadrilateral::GetLowerRight ( void ) const { return m_lowerRight; } //-------------------------------------------------- // bool IsParallelogram // Since we know that the base of the Quadrilateral // is parallel to the x-axis, we can use the // vertical and horizontal distances between the // points to determine parallelism rather than // the more complex Distance() calculation //-------------------------------------------------- bool Quadrilateral::IsParallelogram ( void ) const { return (HorizontalDistance (m_lowerLeft, m_lowerRight) == HorizontalDistance(m_upperLeft, m_upperRight) && (VerticalDistance (m_upperLeft, m_lowerLeft) == VerticalDistance(m_upperRight, m_lowerRight))); } //------------------------------------------------ // IsRectangle // a rectangle is a parallelogram with a right // angle. one right angle + parallelogram // implies all right angles. // A corner makes a right angle if it has // the same X as the corner "above" it and // the same Y as the corner "next" to it // Without loss of generality, check the lower left corner //--------------------------------------------------- bool Quadrilateral::IsRectangle ( void ) const { return IsParallelogram() && m_lowerLeft.GetX() == m_upperLeft.GetX() && m_lowerLeft.GetY() == m_lowerLeft.GetY(); } //----------------------------------------------- // IsSquare // A rectangle with side the same length. // Not necessary to check them all... just check // one horizontal side with on vertical side // once again, since the horizontal sides are // parallel to x-axis (and since it's a rectangle // the vertical sides are parallel to the y-axis, // we can use the horizontal/vertical calculations // rather than the more complex Distance() // ---------------------------------------------- bool Quadrilateral::IsSquare(void) const { return IsRectangle() && HorizontalDistance (m_lowerLeft, m_lowerRight) == VerticalDistance (m_lowerLeft, m_upperRight); } //----------------------------------------------------- // IsTrapezoid // not a parllelogram, but one // one set of sides are parallel // Since either the horizontal bases are // parallel to x-axis or vertical sides are // parallel to y-axis, we can check horizontal/vertical // distances for parallelism //----------------------------------------------------- bool Quadrilateral::IsTrapezoid( void ) const { return !IsParallelogram() && (VerticalDistance(m_upperLeft, m_lowerLeft) == VerticalDistance (m_upperRight, m_lowerLeft) || HorizontalDistance(m_lowerLeft, m_lowerRight) == HorizontalDistance(m_upperRight, m_upperLeft)); } //--------------------------------- // IsIrregular // any quadrilateral that's not // one of the others //--------------------------------- bool Quadrilateral::IsIrregular ( void ) const { return !IsParallelogram() && !IsTrapezoid(); } //------------------------------------------------------ // Area // determines the type of Quarilateral // and calculates it's area. // Per project 2 description, the area of // an irregular Quadrilateral is returned as 0.0 //----------------------------------------------------- double Quadrilateral::Area ( void ) const { if (IsTrapezoid()) return TrapezoidArea(); // parallelogram, rectangle, square all the same else if (IsParallelogram()) return HorizontalDistance(m_lowerLeft, m_lowerRight) * VerticalDistance ( m_lowerLeft, m_upperLeft); else // irregular quadrilateral return 0.0; } //----------------------------------------- // TrapezoidArea // private method called by Area() for // trapezoids. // Area = 1/2 * (sum of parallel sides) * height //---------------------------------------- double Quadrilateral::TrapezoidArea ( void ) const { double sides; double height; // determine which sides are parallel if (VerticalDistance(m_upperLeft, m_lowerLeft ) == VerticalDistance(m_upperRight, m_lowerLeft)) { // "top" and "bottom" parallel (and assumed parallel to x-axis) sides = Distance(m_lowerLeft, m_lowerRight) + Distance(m_upperLeft, m_upperRight); height = VerticalDistance (m_lowerLeft, m_upperLeft); } else { // sides parallel (and assumed parallel to y-axis) sides = Distance (m_lowerLeft, m_upperLeft) + Distance(m_lowerRight, m_upperRight); height = HorizontalDistance(m_lowerLeft, m_lowerRight); } return 0.5 * sides * height; } //--------------------------------------------- // Perimeter // returns the perimeter of any quadrilateral // by adding the lengths of the sides //--------------------------------------------- double Quadrilateral::Perimeter ( void ) const { return Distance (m_lowerLeft, m_upperLeft) + Distance (m_upperLeft, m_upperRight) + Distance (m_upperRight, m_lowerRight) + Distance (m_lowerRight, m_lowerLeft); }