/////////////////////////////////////////////////////////////////////// // Name: BoundaryShapeManager.cpp // // *** INTERACTIVE DATA VISUALIZATION (IDV) PROPRIETARY INFORMATION *** // // Copyright (c) 2002-2003 IDV, Inc. // All Rights Reserved. // // IDV, Inc. // 1233 Washington St. Suite 610 // Columbia, SC 29201 // Voice: (803) 799-1699 // Fax: (803) 931-0320 // Web: http://www.idvinc.com // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Interactive Data Visualization and may not // be copied or disclosed except in accordance with the terms of that // agreement. /////////////////////////////////////////////////////////////////////// // Preprocessor #include "StdAfx.h" #include #include "../eterbase/Random.h" #include "BoundaryShapeManager.h" using namespace std; /////////////////////////////////////////////////////////////////////// // CBoundaryShapeManager::CBoundaryShapeManager CBoundaryShapeManager::CBoundaryShapeManager() { } /////////////////////////////////////////////////////////////////////// // CBoundaryShapeManager::~CBoundaryShapeManager CBoundaryShapeManager::~CBoundaryShapeManager() { } /////////////////////////////////////////////////////////////////////// // CBoundaryShapeManager::LoadBsfFile bool CBoundaryShapeManager::LoadBsfFile(const char* pszFilename) { bool bSuccess = true; try { FILE* pFile = fopen(pszFilename, "rb"); if (pFile) { // number of boundary shapes unsigned int nNumBoundaries; if (fread(&nNumBoundaries, sizeof(unsigned int), 1, pFile) == 1) { for (unsigned int i = 0; i < nNumBoundaries && bSuccess; ++i) { SBoundaryShape sShape; // number of contours for this shape unsigned int nNumContours; if (fread(&nNumContours, sizeof(unsigned int), 1, pFile) == 1) { for (unsigned int j = 0; j < nNumContours && bSuccess; ++j) { // number of points in this contour vector vPoints; unsigned int nNumPoints; if (fread(&nNumPoints, sizeof(unsigned int), 1, pFile) == 1) { // read the points for (unsigned int k = 0; k < nNumPoints && bSuccess; ++k) { SPoint sPoint; if (fread(sPoint.m_afData, sizeof(float), 3, pFile) == 3) { vPoints.push_back(sPoint); // update extents if (j == 0 && k == 0) { // first point of this shape memcpy(sShape.m_afMin, sPoint.m_afData, 3 * sizeof(float)); memcpy(sShape.m_afMax, sPoint.m_afData, 3 * sizeof(float)); } else { // check extents for (int l = 0; l < 3; ++l) { if (sPoint.m_afData[l] < sShape.m_afMin[l]) sShape.m_afMin[l] = sPoint.m_afData[l]; else if (sPoint.m_afData[l] > sShape.m_afMax[l]) sShape.m_afMax[l] = sPoint.m_afData[l]; } } } else { m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read point"; bSuccess = false; } } sShape.m_vContours.push_back(vPoints); } else { m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read number of points"; bSuccess = false; } } m_vBoundaries.push_back(sShape); } else { m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read number of contours"; bSuccess = false; } } } else { m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Failed to read number of boundaries"; bSuccess = false; } fclose(pFile); } else { m_strCurrentError = string("Error in CBoundaryShapeManager::LoadBsfFile(): Could not open ") + string(pszFilename); bSuccess = false; } } catch(...) { m_strCurrentError = "Error in CBoundaryShapeManager::LoadBsfFile(): Unknown exception"; } return bSuccess; } /////////////////////////////////////////////////////////////////////// // CBoundaryShapeManager::PointInside bool CBoundaryShapeManager::PointInside(float fX, float fY) { bool bInside = false; for (DWORD i = 0; i < m_vBoundaries.size() && !bInside; ++i) bInside = PointInShape(m_vBoundaries[i], fX, fY); return bInside; } /////////////////////////////////////////////////////////////////////// // CBoundaryShapeManager::PointInShape bool CBoundaryShapeManager::PointInShape(SBoundaryShape& sShape, float fX, float fY) { bool bInside = false; for (DWORD k = 0; k < sShape.m_vContours.size(); ++k) { for (DWORD i = 0, j = sShape.m_vContours[k].size() - 1; i < sShape.m_vContours[k].size(); j = i++) { if ((((sShape.m_vContours[k][i][1] <= fY) && (fY < sShape.m_vContours[k][j][1])) || ((sShape.m_vContours[k][j][1] <= fY) && (fY < sShape.m_vContours[k][i][1]))) && (fX < (sShape.m_vContours[k][i][0] - sShape.m_vContours[k][i][0]) * (fY - sShape.m_vContours[k][i][1]) / (sShape.m_vContours[k][j][1] - sShape.m_vContours[k][i][1]) + sShape.m_vContours[k][i][0])) { bInside = !bInside; } } } return bInside; } /////////////////////////////////////////////////////////////////////// // CBoundaryShapeManager::RandomPoint bool CBoundaryShapeManager::RandomPoint(float& fX, float& fY) { bool bSuccess = false; if (m_vBoundaries.size() > 0) { // pick a random boundary shape int nIndex = random_range(0, m_vBoundaries.size() - 1); SBoundaryShape& sShape = m_vBoundaries[nIndex]; // pick a point at random within its extents fX = frandom(sShape.m_afMin[0], sShape.m_afMax[0]); fY = frandom(sShape.m_afMin[1], sShape.m_afMax[1]); // try it bSuccess = PointInShape(sShape, fX, fY); } return bSuccess; }