3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 06/01/2010 Added this text. :-)
19 #include "mathextra.h"
37 * Adds a point to the internal list
39 * @param p co-ordinate of the point
41 void InfoArea::addPoint(const Vector & p)
43 if (thePoints.empty())
52 void InfoArea::reset()
60 * Closes the polygon if it is not closed already.
62 void InfoArea::close()
64 if (isValid() && isClosed() == false)
66 thePoints.append(thePoints.first());
68 DEBUG->print("InfoArea::close: closed");
73 * @retval true If the area is closed (i.e. start point and end point are
75 * @retval false Otherwise.
77 bool InfoArea::isClosed()
79 return (thePoints.first().distanceTo(thePoints.last()) < 1.0e-4);
83 * @retval true If the area is defined (i.e. there are at least 3 points)
84 * @retval false If there are only two or less points.
86 bool InfoArea::isValid()
88 DEBUG->print("InfoArea::isValid: count: %d", thePoints.count());
89 return (thePoints.count() > 2);
93 * Calculates the area and the circumference of the area.
95 void InfoArea::calculate()
103 // at least 3 points needed for an area
106 ptFirst = thePoints.last();
107 thePoints.pop_back();
111 while (!thePoints.empty())
113 p2 = thePoints.last();
114 thePoints.pop_back();
116 area += calcSubArea(p1, p2);
117 circumference += p1.distanceTo(p2);
118 //if (p1 != ptFirst) {
124 area += calcSubArea(p1, ptFirst);
125 circumference += p1.distanceTo(ptFirst);
134 double InfoArea::getArea()
139 double InfoArea::getCircumference()
141 return circumference;
144 int InfoArea::count()
146 return thePoints.count();
150 * Calculates a sub area.
152 * @param p1 first point
153 * @param p2 second point
155 double InfoArea::calcSubArea(const Vector & p1, const Vector & p2)
157 double width = p2.x - p1.x;
158 double height = (p1.y - baseY) + (p2.y - baseY);
160 return (width * height) / 2.0;
163 /*! Calculates a distance
164 \param _p1 first point
165 \param _p2 second point
168 InfoArea::calcDistance(Vector *_p1, Vector *_p2)
170 return mtGetDistance(_p1->getX(), _p1->getY(), _p2->getX(), _p2->getY());