#ifndef GEOMETRY_VECTOR_H_
#define GEOMETRY_VECTOR_H_
+#include <cmath>
+#include <limits>
#include <ostream>
namespace geometry {
Scalar X() const { return x; }
Scalar Y() const { return y; }
+ Scalar Index(Scalar lineLength) const { return Y() * lineLength + X(); }
+ static Vector<Scalar> FromIndex(Scalar index, Scalar lineLength) {
+ return Vector<Scalar>(index % lineLength, index / lineLength);
+ }
+
+ void Lock(const Vector<Scalar> &to);
+
private:
Scalar x, y;
return Vector<T>(-v.X(), -v.Y());
}
+template<class T>
+inline Vector<T> operator *(const Vector<T> &v1, const Vector<T> &v2) {
+ return Vector<T>(v1.X() * v2.X(), v1.Y() * v2.Y());
+}
template<class T>
inline Vector<T> operator *(const Vector<T> &v, T s) {
return Vector<T>(v.X() * s, v.Y() * s);
return Vector<T>(s * v.X(), s * v.Y());
}
+template<class T>
+inline Vector<T> operator /(const Vector<T> &v1, const Vector<T> &v2) {
+ return Vector<T>(v1.X() / v2.X(), v1.Y() / v2.Y());
+}
template<class T>
inline Vector<T> operator /(const Vector<T> &v, T s) {
return Vector<T>(v.X() / s, v.Y() / s);
}
+template<class T>
+inline Vector<T> operator /(T s, const Vector<T> &v) {
+ return Vector<T>(s / v.X(), s / v.Y());
+}
+
+template<class T>
+inline Vector<T> operator %(const Vector<T> &v1, const Vector<T> &v2) {
+ return Vector<T>(v1.X() % v2.X(), v1.Y() % v2.Y());
+}
+template<>
+inline Vector<float> operator %(const Vector<float> &v1, const Vector<float> &v2) {
+ return Vector<float>(std::fmod(v1.X(), v2.X()), std::fmod(v1.Y(), v2.Y()));
+}
+template<>
+inline Vector<double> operator %(const Vector<double> &v1, const Vector<double> &v2) {
+ return Vector<double>(std::fmod(v1.X(), v2.X()), std::fmod(v1.Y(), v2.Y()));
+}
+template<>
+inline Vector<long double> operator %(const Vector<long double> &v1, const Vector<long double> &v2) {
+ return Vector<long double>(std::fmod(v1.X(), v2.X()), std::fmod(v1.Y(), v2.Y()));
+}
+template<class T>
+inline Vector<T> operator %(const Vector<T> &v, T s) {
+ return Vector<T>(v.X() % s, v.Y() % s);
+}
+template<>
+inline Vector<float> operator %(const Vector<float> &v, float s) {
+ return Vector<float>(std::fmod(v.X(), s), std::fmod(v.Y(), s));
+}
+template<>
+inline Vector<double> operator %(const Vector<double> &v, double s) {
+ return Vector<double>(std::fmod(v.X(), s), std::fmod(v.Y(), s));
+}
+template<>
+inline Vector<long double> operator %(const Vector<long double> &v, long double s) {
+ return Vector<long double>(std::fmod(v.X(), s), std::fmod(v.Y(), s));
+}
template<class T>
inline bool operator ==(const Vector<T> &lhs, const Vector<T> &rhs) {
return out;
}
+
+template <class Scalar>
+void Vector<Scalar>::Lock(const Vector<Scalar> &to) {
+ Vector<Scalar> half(to / Scalar(2));
+ Vector<Scalar> dist((*this) % to);
+
+ if (dist.X() > half.X()) {
+ x += (to.X() - dist.X());
+ } else {
+ x -= dist.X();
+ }
+
+ if (dist.Y() > half.Y()) {
+ y += (to.Y() - dist.Y());
+ } else {
+ y -= dist.Y();
+ }
+}
+
+
}
#endif /* GEOMETRY_VECTOR_H_ */
const Area &Map::AreaAt(const Vector<int> &offset) const {
if (numAreas > 0) {
Vector<int> coords(TileCoordinates(offset));
- Vector<int> areaOffset(coords.X() / areas[0].Width(), coords.Y() / areas[0].Height());
- int areaIndex(areaOffset.Y() * width + areaOffset.X());
+ Vector<int> areaOffset(coords / areas[0].Size());
+ int areaIndex(areaOffset.Index(width));
if (areaIndex < numAreas) {
return areas[areaIndex];
}
const Tile &Map::TileAt(const Vector<int> &offset) const {
const Area &area(AreaAt(offset));
- Vector<int> tileOffset((offset.X() / tileset->Width()) % area.Width(), (offset.Y() / tileset->Height()) % area.Height());
+ Vector<int> tileOffset(TileCoordinates(offset) % area.Size());
return area.TileAt(tileOffset);
}
}
Vector<int> Map::TileCoordinates(const Vector<int> &position) const {
- return Vector<int>(position.X() / tileset->Width(), position.Y() / tileset->Height());
+ return position / tileset->Size();
}
// TODO: skip invisible areas
for (int i(0); i < numAreas; ++i) {
const Area &area(areas[i]);
- Vector<int> offset(
- inOffset.X() + (i % width) * area.Width() * tileset->Width(),
- inOffset.Y() + (i / width) * area.Height() * tileset->Height());
+ Vector<int> offset(inOffset + Vector<int>::FromIndex(i, width) * area.Size() * tileset->Size());
area.Render(dest, tileset, offset);
}
}