⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lattice.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
#include <fstream.h>
#include <limits.h>
#include "lattice.h"

// error handling
int mgcLattice::verbose = 0;
unsigned mgcLattice::error = 0;
const unsigned mgcLattice::allocation_failed = 0x00000001;
const unsigned mgcLattice::nonpositive_bound = 0x00000002;
const unsigned mgcLattice::zero_dimension    = 0x00000004;
const unsigned mgcLattice::invalid_dimension = 0x00000008;
const char* mgcLattice::message[4] = {
	"failed to allocate memory",
	"a lattice bound is nonpositive",
	"zero dimension in variable argument list",
	"invalid dimension requested for lattice bound"
};

//===========================================================================
void mgcLattice::
Create (int _dimensions, const int* initial)
{
	dimensions = _dimensions;
	bound = 0;
	offset = 0;
	quantity = 0;

	if ( dimensions == 0 )
		return;

	if ( (bound = new int[dimensions]) == 0 ) {
		Report(allocation_failed);
		return;
	}

	if ( (offset = new int[dimensions]) == 0 ) {
		Report(allocation_failed);
		delete[] bound;
		bound = 0;
		return;
	}

	int d;
	if ( initial == 0 ) {
		for (d = 0; d < dimensions; d++) {
			bound[d] = 0;
			offset[d] = 0;
		}
		return;
	}

	for (d = 0; d < dimensions; d++) {
		bound[d] = initial[d];
		if ( bound[d] <= 0 ) {  // can this be changed to "< 0" ?
			Report(nonpositive_bound);
			delete[] bound;
			delete[] offset;
			bound = 0;
			offset = 0;
			return;
		};
	}

	// calculate number of lattice points
	quantity = 1;
	for (d = 0; d < dimensions; d++)
		quantity *= bound[d];

	// calculate offset indices of neighboring lattice points
	offset[0] = 1;
	for (d = 1; d < dimensions; d++)
		offset[d] = bound[d-1]*offset[d-1];
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (int _dimensions, const int* initial)
{
	Create(_dimensions,initial);
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (int _dimensions, int initial_all)
{
	if ( _dimensions == 0 ) {
		Create(0,0);
		// no error, default image constructor creates 0-dim image
        // and calls this routine
		return;
	}

	int* initial = new int[_dimensions];
	for (int d = 0; d < _dimensions; d++)
		initial[d] = initial_all;

	Create(_dimensions,initial);
	delete[] initial;
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (int _dimensions, int initial0, int initial1, ...)
{
	if ( _dimensions < 2 ) {
		Create(0,0);
		Report(zero_dimension);
		return;
	}

	int* initial = new int[_dimensions];
	initial[0] = initial0;
	initial[1] = initial1;

	va_list ap;
	va_start(ap,initial1);
	for (int d = 2; d < _dimensions; d++)
		initial[d] = va_arg(ap,int);
	va_end(ap);

	Create(_dimensions,initial);
	delete[] initial;
}
//---------------------------------------------------------------------------
mgcLattice::
mgcLattice (const mgcLattice &lattice)
{
	Create(lattice.dimensions,lattice.bound);
}
//---------------------------------------------------------------------------
mgcLattice::
~mgcLattice ()
{
	delete[] bound;
    delete[] offset;
}
//---------------------------------------------------------------------------
int mgcLattice::
Bound (int d) const
{
	if ( 0 <= d && d < dimensions )
		return bound[d];

	Report(invalid_dimension);
	return -1;
}
//---------------------------------------------------------------------------
mgcLattice& mgcLattice::
operator= (const mgcLattice &lattice)
{
	if ( dimensions != lattice.dimensions ) {
		delete[] bound;
		delete[] offset;
		Create(lattice.dimensions,lattice.bound);
	}

	for (int d = 0; d < dimensions; d++) {
		bound[d] = lattice.bound[d];
		offset[d] = lattice.offset[d];
	}
	quantity = lattice.quantity;

	return *this;
}
//---------------------------------------------------------------------------
int mgcLattice::
operator== (const mgcLattice& lattice) const
{
	if ( dimensions != lattice.dimensions )
		return 0;
	for (int d = 0; d < dimensions; d++)
		if ( bound[d] != lattice.bound[d] )
			return 0;
	return 1;
}
//---------------------------------------------------------------------------
int mgcLattice::
Index (const mgcCoordinate& coordinate) const
{
	int index = coordinate[0];
	for (int d = 1; d < dimensions; d++)
		index += offset[d]*coordinate[d];
	return index;
}
//---------------------------------------------------------------------------
mgcCoordinate mgcLattice::
Coordinate (int index) const
{
	mgcCoordinate coordinate(dimensions);
	for (int d = 0; d < dimensions; d++) {
		coordinate[d] = index % bound[d];
		index /= bound[d];
	}
	return coordinate;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryDistance (const mgcCoordinate& coordinate) const
{
	if ( dimensions != coordinate.Dimensions() )
		return -1;

	int distance = INT_MAX;

	for (int d = 0; d < dimensions; d++) {
		int test0 = coordinate[d];
		if ( test0 < distance )
			distance = test0;

		int test1 = bound[d]-1-test0;
		if ( test1 < distance )
			distance = test1;
	}

	return distance;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryDistance (int index) const
{
	int distance = INT_MAX;

	for (int d = 0; d < dimensions; d++) {
		int test0 = index % bound[d];
		if ( test0 < distance )
			distance = test0;

		int test1 = bound[d]-1-test0;
		if ( test1 < distance )
			distance = test1;

		index /= bound[d];
	}

	return distance;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryType (const mgcCoordinate& coordinate) const
{
	if ( dimensions != coordinate.Dimensions() )
		return -1;

	int btype = 0;

	for (int d = 0; d < dimensions; d++) {
		int test = coordinate[d];
		if ( test == 0 || test == bound[d]-1 )
			btype++;
	}

	return btype;
}
//---------------------------------------------------------------------------
int mgcLattice::
BoundaryType (int index) const
{
	int btype = 0;

	for (int d = 0; d < dimensions; d++) {
		int test = index % bound[d];
		if ( test == 0 || test == bound[d]-1 )
			btype++;
		index /= bound[d];
	}

	return btype;
}
//---------------------------------------------------------------------------
int mgcLattice::
ClampMin (int dim, int index, int delta) const
{
	int test = offset[dim]*((index/offset[dim])%bound[dim]);
	return delta <= test ? index-delta : index-test;
}
//---------------------------------------------------------------------------
int mgcLattice::
ClampMax (int dim, int index, int delta) const
{
	int test = offset[dim]*(bound[dim]-1-((index/offset[dim])%bound[dim]));
	return delta <= test ? index+delta : index+test;
}
//---------------------------------------------------------------------------
ostream& operator<< (ostream& ostr, const mgcLattice& lattice)
{
	ostr << "dims    = " << lattice.dimensions << endl;
	if ( lattice.dimensions > 0 ) {
		ostr << "bound   = (" << lattice.bound[0];
		int d;
		for (d = 1; d < lattice.dimensions; d++)
			ostr << ',' << lattice.bound[d];
		ostr << ")" << endl;

		ostr << "offset  = (" << lattice.offset[0];
		for (d = 1; d < lattice.dimensions; d++)
			ostr << ',' << lattice.offset[d];
		ostr << ")" << endl;
	}
	return ostr;
}
//---------------------------------------------------------------------------
int mgcLattice::
Number (unsigned single_error)
{
	int result;
	for (result = -1; single_error; single_error >>= 1)
		result++;
	return result;
}
//---------------------------------------------------------------------------
void mgcLattice::
Report (unsigned single_error)
{
	if ( verbose )
		cout << "mgcLattice: " << message[Number(single_error)] << endl;
	else
		ofstream("lattice.err",ios::out|ios::app)
			 << "mgcLattice: " << message[Number(single_error)] << endl;

	error |= single_error;
}
//---------------------------------------------------------------------------
void mgcLattice::
Report (ostream& ostr)
{
	for (unsigned single_error = 1; single_error; single_error <<= 1) {
		if ( error & single_error )
			ostr << "mgcLattice: " << message[Number(single_error)] << endl;
	}
	error = 0;
}
//===========================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -