]> git.localhorst.tv Git - l2e.git/commitdiff
more Vector operations
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 5 Oct 2012 13:54:50 +0000 (15:54 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 5 Oct 2012 14:49:52 +0000 (16:49 +0200)
there are not real vector operations in a mathematical sense, but are useful nonetheless

src/geometry/Vector.h
src/map/Area.h
src/map/Map.cpp

index 7c698ff4af0a11d9b707cd0b51503142e016f475..c6a42fbba069e4b98bdac5acfb5bff9ba2242de5 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef GEOMETRY_VECTOR_H_
 #define GEOMETRY_VECTOR_H_
 
+#include <cmath>
+#include <limits>
 #include <ostream>
 
 namespace geometry {
@@ -27,6 +29,13 @@ public:
        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;
 
@@ -74,6 +83,10 @@ inline Vector<T> operator -(const Vector<T> &v) {
        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);
@@ -83,10 +96,51 @@ 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<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) {
@@ -104,6 +158,26 @@ inline std::ostream &operator <<(std::ostream &out, const Vector<T> &v) {
        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_ */
index 9832809e93349519461e13c037fa0924e741fd22..e2b6a1ede7a0a0dcbde2c8502bfd8df3b4180a41 100644 (file)
@@ -25,6 +25,7 @@ public:
 public:
        int Width() const { return width; }
        int Height() const { return numTiles / width + (numTiles % width ? 1 : 0); }
+       geometry::Vector<int> Size() const { return geometry::Vector<int>(Width(), Height()); }
        const Tile &TileAt(const geometry::Vector<int> &) const;
 
        void Render(SDL_Surface *dest, const graphics::Sprite *tileset, const geometry::Vector<int> &offset) const;
index 10b74d079a01d43b422fa7719bb1a84298aa8d8d..20f2fa575585eebd8cc0fe070d4fafb50f2b1a00 100644 (file)
@@ -31,8 +31,8 @@ Map::Map()
 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];
                }
@@ -42,7 +42,7 @@ const Area &Map::AreaAt(const Vector<int> &offset) const {
 
 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);
 }
 
@@ -58,7 +58,7 @@ Trigger *Map::TriggerAt(const geometry::Vector<int> &offset) {
 }
 
 Vector<int> Map::TileCoordinates(const Vector<int> &position) const {
-       return Vector<int>(position.X() / tileset->Width(), position.Y() / tileset->Height());
+       return position / tileset->Size();
 }
 
 
@@ -66,9 +66,7 @@ void Map::Render(SDL_Surface *dest, const Vector<int> &inOffset) const {
        // 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);
        }
 }