214 lines
5.8 KiB
C++
214 lines
5.8 KiB
C++
///////////////////////////////////////////////////////////////////////
|
|
// 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 <windows.h>
|
|
#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<SPoint> 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;
|
|
}
|