1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 09:35:28 +00:00

added CellCoordinates and CellSelection classes

This commit is contained in:
Marc Zinnschlag 2014-04-07 13:42:00 +02:00
parent 324b2743d4
commit 67965ec10c
5 changed files with 243 additions and 1 deletions

View File

@ -24,7 +24,7 @@ opencs_units (model/world
opencs_units_noqt (model/world opencs_units_noqt (model/world
universalid record commands columnbase scriptcontext cell refidcollection universalid record commands columnbase scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world

View File

@ -0,0 +1,60 @@
#include "cellcoordinates.hpp"
#include <ostream>
#include <sstream>
CSMWorld::CellCoordinates::CellCoordinates() : mX (0), mY (0) {}
CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {}
int CSMWorld::CellCoordinates::getX() const
{
return mX;
}
int CSMWorld::CellCoordinates::getY() const
{
return mY;
}
CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move (int x, int y) const
{
return CellCoordinates (mX + x, mY + y);
}
std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) const
{
// we ignore the worldspace for now, since there is only one (will change in 1.1)
std::ostringstream stream;
stream << "#" << mX << " " << mY;
return stream.str();
}
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
{
return left.getX()==right.getX() && left.getY()==right.getY();
}
bool CSMWorld::operator!= (const CellCoordinates& left, const CellCoordinates& right)
{
return !(left==right);
}
bool CSMWorld::operator< (const CellCoordinates& left, const CellCoordinates& right)
{
if (left.getX()<right.getX())
return true;
if (left.getX()>right.getX())
return false;
return left.getY()<right.getY();
}
std::ostream& CSMWorld::operator<< (std::ostream& stream, const CellCoordinates& coordiantes)
{
return stream << coordiantes.getX() << ", " << coordiantes.getY();
}

View File

@ -0,0 +1,42 @@
#ifndef CSM_WOLRD_CELLCOORDINATES_H
#define CSM_WOLRD_CELLCOORDINATES_H
#include <iosfwd>
#include <string>
#include <QMetaType>
namespace CSMWorld
{
class CellCoordinates
{
int mX;
int mY;
public:
CellCoordinates();
CellCoordinates (int x, int y);
int getX() const;
int getY() const;
CellCoordinates move (int x, int y) const;
///< Return a copy of *this, moved by the given offset.
std::string getId (const std::string& worldspace) const;
///< Return the ID for the cell at these coordinates.
};
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
bool operator!= (const CellCoordinates& left, const CellCoordinates& right);
bool operator< (const CellCoordinates& left, const CellCoordinates& right);
std::ostream& operator<< (std::ostream& stream, const CellCoordinates& coordiantes);
}
Q_DECLARE_METATYPE (CSMWorld::CellCoordinates)
#endif

View File

@ -0,0 +1,83 @@
#include "cellselection.hpp"
#include <cmath>
#include <stdexcept>
#include <limits>
CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::begin() const
{
return mCells.begin();
}
CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::end() const
{
return mCells.end();
}
bool CSMWorld::CellSelection::add (const CellCoordinates& coordinates)
{
return mCells.insert (coordinates).second;
}
void CSMWorld::CellSelection::remove (const CellCoordinates& coordinates)
{
mCells.erase (coordinates);
}
bool CSMWorld::CellSelection::has (const CellCoordinates& coordinates) const
{
return mCells.find (coordinates)!=end();
}
int CSMWorld::CellSelection::getSize() const
{
return mCells.size();
}
CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const
{
if (mCells.empty())
throw std::logic_error ("call of getCentre on empty cell selection");
double x = 0;
double y = 0;
for (Iterator iter = begin(); iter!=end(); ++iter)
{
x += iter->getX();
y += iter->getY();
}
x /= mCells.size();
y /= mCells.size();
Iterator closest = begin();
double distance = std::numeric_limits<double>::max();
for (Iterator iter (begin()); iter!=end(); ++iter)
{
double deltaX = x - iter->getX();
double deltaY = y - iter->getY();
double delta = std::sqrt (deltaX * deltaX + deltaY * deltaY);
if (delta<distance)
{
distance = delta;
closest = iter;
}
}
return *closest;
}
void CSMWorld::CellSelection::move (int x, int y)
{
Container moved;
for (Iterator iter = begin(); iter!=end(); ++iter)
moved.insert (iter->move (x, y));
mCells.swap (moved);
}

View File

@ -0,0 +1,57 @@
#ifndef CSM_WOLRD_CELLSELECTION_H
#define CSM_WOLRD_CELLSELECTION_H
#include <set>
#include <QMetaType>
#include "cellcoordinates.hpp"
namespace CSMWorld
{
/// \brief Selection of cells in a paged worldspace
///
/// \note The CellSelection does not specify the worldspace it applies to.
class CellSelection
{
public:
typedef std::set<CellCoordinates> Container;
typedef Container::const_iterator Iterator;
private:
Container mCells;
public:
Iterator begin() const;
Iterator end() const;
bool add (const CellCoordinates& coordinates);
///< Ignored if the cell specified by \a coordinates is already part of the selection.
///
/// \return Was a cell added to the collection?
void remove (const CellCoordinates& coordinates);
///< ignored if the cell specified by \a coordinates is not part of the selection.
bool has (const CellCoordinates& coordinates) const;
///< \return Is the cell specified by \a coordinates part of the selection?
int getSize() const;
///< Return number of cells.
CellCoordinates getCentre() const;
///< Return the selected cell that is closest to the geometric centre of the selection.
///
/// \attention This function must not be called on selections that are empty.
void move (int x, int y);
};
}
Q_DECLARE_METATYPE (CSMWorld::CellSelection)
#endif