// Domain.cpp : implementation file // #include "stdafx.h" //#include "OTSData.h" #include "Domain.h" #include "XMLSerialization.h" namespace OTSDATA { using namespace xmls; // CDomain // constructor CDomain::CDomain() { // initialization Init(); } CDomain::CDomain(DOMAIN_SHAPE a_nShape, CRect a_rectDomain) { // initialization Init(); // assign class members m_nShape = a_nShape; m_rectDomain = a_rectDomain; } // copy constructor CDomain::CDomain(const CDomain& a_oSource) { // can't copy itself if (&a_oSource == this) { return; } // copy data over Duplicate(a_oSource); } // copy constructor CDomain::CDomain(CDomain* a_poSource) { // input check ASSERT(a_poSource); if (!a_poSource) { return; } // can't copy itself if (a_poSource == this) { return; } // copy data over Duplicate(*a_poSource); } // =operator CDomain& CDomain::operator=(const CDomain& a_oSource) { // cleanup Cleanup(); // copy the class data over Duplicate(a_oSource); // return class return *this; } // ==operator BOOL CDomain::operator==(const CDomain& a_oSource) { return m_nShape == a_oSource.m_nShape && m_rectDomain == a_oSource.m_rectDomain; } // destructor CDomain::~CDomain() { // cleanup Cleanup(); } // CDomain functions // public // check if the region is valid BOOL CDomain::IsInvalid() const { return (m_nShape < DOMAIN_SHAPE::MIN) || m_nShape > DOMAIN_SHAPE::MAX || m_rectDomain.IsRectEmpty(); } void CDomain::SetPolygonPoint(const std::vector* a_PolygonPoint) { std::vector ps = *a_PolygonPoint; m_PolygonPoint.clear(); for (auto p : ps) { m_PolygonPoint.push_back(p); } } // check if have common area with the given domain BOOL CDomain::IntersectDomain(const CDomain& a_oDomain) { // return FALSE if any domain of the two is invalid if (IsInvalid() || a_oDomain.IsInvalid()) { return FALSE; } // create two CRgn objects with the two region objects CRect rectCur, rectGiven; rectCur = GetDomainRect(); rectGiven = a_oDomain.GetDomainRect(); CRgn rgnCur, rgnGiven, rgnTest; BOOL bRgnCur, bRgnGiven; bRgnCur = rgnTest.CreateEllipticRgnIndirect(rectCur); if (IsRound()) { bRgnCur = rgnCur.CreateEllipticRgnIndirect(rectCur); } else { bRgnCur = rgnCur.CreateRectRgnIndirect(rectCur); } if (a_oDomain.IsRound()) { bRgnGiven = rgnGiven.CreateEllipticRgnIndirect(rectGiven); } else { rgnGiven.CreateRectRgnIndirect(rectGiven); } // combine the two CRgn objects with RGN_AND int nCombineResult = rgnTest.CombineRgn(&rgnCur, &rgnGiven, RGN_AND); // return TRUE if combine success and combine result is not empty return (nCombineResult != ERROR) && (nCombineResult != NULLREGION); } // check if the point is in domain BOOL CDomain::PtInDomain(const CPoint& a_poiCheck) const { // return FALSE if is invalid if (IsInvalid()) { return FALSE; } // check sharp if (IsRound()) { // round double dRoundRegionRadius = (double)GetDomainRect().Width() / 2000.0; dRoundRegionRadius = dRoundRegionRadius * dRoundRegionRadius; double dDisToRegioCenter; double dX, dY; dX = (double)abs(GetDomainCenter().x - a_poiCheck.x) / 1000; dY = (double)abs(GetDomainCenter().y - a_poiCheck.y) / 1000; dX = dX * dX; dY = dY * dY; dDisToRegioCenter = dX + dY; if (dRoundRegionRadius >= dDisToRegioCenter) { // in region return TRUE; } else { // not in region return FALSE; } } else { // rectangle // use CRect method return GetDomainRect().PtInRect(a_poiCheck); } } // check if the given domain is in domain BOOL CDomain::DomainInDomain(const CDomain& a_oDomain) { // return FALSE if any domain of the two is invalid if (IsInvalid() || a_oDomain.IsInvalid()) { return FALSE; } // create two CRgn objects with the two domain objects CRect rectCur, rectGiven; rectCur = GetDomainRect(); rectGiven = a_oDomain.GetDomainRect(); CRgn rgnCur, rgnGiven, rgnTest; BOOL bRgnCur, bRgnGiven; bRgnCur = rgnTest.CreateEllipticRgnIndirect(rectCur); if (IsRound()) { bRgnCur = rgnCur.CreateEllipticRgnIndirect(rectCur); } else { bRgnCur = rgnCur.CreateRectRgnIndirect(rectCur); } if (a_oDomain.IsRound()) { bRgnGiven = rgnGiven.CreateEllipticRgnIndirect(rectGiven); } else { bRgnGiven = rgnGiven.CreateRectRgnIndirect(rectGiven); } // combine the two CRgn objects with RGN_AND int nCombineResult = rgnTest.CombineRgn(&rgnCur, &rgnGiven, RGN_AND); // return FALSE if combine failed or combine result is empty if (nCombineResult == ERROR || nCombineResult == NULLREGION) { return FALSE; } // the combined region equals the test domain means that the test domain is in the domain, return TRUE return rgnTest.EqualRgn(&rgnGiven); } // cleanup void CDomain::Cleanup() { // need to do nothing at the moment m_PolygonPoint.clear(); } // initialization void CDomain::Init() { m_nShape = DOMAIN_SHAPE::INVALID; m_rectDomain = CRect(0, 0, 0, 0); m_PolygonPoint.clear(); } // duplication void CDomain::Duplicate(const CDomain& a_oSource) { // initialization Init(); // copy data over m_nShape = a_oSource.m_nShape; m_rectDomain = a_oSource.m_rectDomain; m_PolygonPoint = a_oSource.m_PolygonPoint; } }