summaryrefslogtreecommitdiffstats
path: root/src/math/vector.h
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-05-03 13:35:32 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-05-03 13:35:32 +0200
commitf67a62fb28c882b1650b827730bac72f404e2c47 (patch)
tree18ea8d7a826ed304250e16ceadca181ef4771259 /src/math/vector.h
parentea442a887d562e95fa91186a4333c830ab5543e7 (diff)
downloadcolobot-f67a62fb28c882b1650b827730bac72f404e2c47.tar.gz
colobot-f67a62fb28c882b1650b827730bac72f404e2c47.tar.bz2
colobot-f67a62fb28c882b1650b827730bac72f404e2c47.zip
Structs continued
Diffstat (limited to 'src/math/vector.h')
-rw-r--r--src/math/vector.h157
1 files changed, 124 insertions, 33 deletions
diff --git a/src/math/vector.h b/src/math/vector.h
index 455042b..48db4c2 100644
--- a/src/math/vector.h
+++ b/src/math/vector.h
@@ -26,20 +26,6 @@
#include <cmath>
-/*
- TODO
-
-void RotatePoint(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p);
-void RotatePoint2(D3DVECTOR center, float angleH, float angleV, D3DVECTOR &p);
-
-BOOL Intersect(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR d, D3DVECTOR e, D3DVECTOR &i);
-BOOL IntersectY(D3DVECTOR a, D3DVECTOR b, D3DVECTOR c, D3DVECTOR &p);
-
-D3DVECTOR RotateView(D3DVECTOR center, float angleH, float angleV, float dist);
-D3DVECTOR LookatPoint( D3DVECTOR eye, float angleH, float angleV, float length );
-
- */
-
// Math module namespace
namespace Math
{
@@ -73,7 +59,7 @@ struct Vector
}
//! Creates a vector from given values
- inline Vector(float x, float y, float z)
+ inline explicit Vector(float x, float y, float z)
{
this->x = x;
this->y = y;
@@ -135,6 +121,9 @@ struct Vector
return acos(CosAngle(right));
}
+
+ /* Operators */
+
//! Returns the inverted vector
inline Vector operator-() const
{
@@ -206,7 +195,16 @@ struct Vector
{
return Vector(left.x / right, left.y / right, left.z / right);
}
-};
+
+}; // struct Point
+
+//! Checks if two vectors are equal within given \a tolerance
+inline bool VectorsEqual(const Vector &a, const Vector &b, float tolerance = TOLERANCE)
+{
+ return IsEqual(a.x, b.x, tolerance)
+ && IsEqual(a.y, b.y, tolerance)
+ && IsEqual(a.z, b.z, tolerance);
+}
//! Convenience function for getting normalized vector
inline Vector Normalize(const Vector &v)
@@ -234,27 +232,19 @@ inline float Angle(const Vector &a, const Vector &b)
return a.Angle(b);
}
-//! Checks if two vectors are equal within given \a tolerance
-inline bool VectorsEqual(const Vector &a, const Vector &b, float tolerance = TOLERANCE)
-{
- return IsEqual(a.x, b.x, tolerance)
- && IsEqual(a.y, b.y, tolerance)
- && IsEqual(a.z, b.z, tolerance);
-}
-
//! Returns the distance between two points
inline float Distance(const Vector &a, const Vector &b)
{
- return std::sqrt( (a.x-b.x)*(a.x-b.x) +
- (a.y-b.y)*(a.y-b.y) +
- (a.z-b.z)*(a.z-b.z) );
+ return sqrt( (a.x-b.x)*(a.x-b.x) +
+ (a.y-b.y)*(a.y-b.y) +
+ (a.z-b.z)*(a.z-b.z) );
}
//! Returns the distance between projections on XZ plane of two vectors
inline float DistanceProjected(const Vector &a, const Vector &b)
{
- return std::sqrt( (a.x-b.x)*(a.x-b.x) +
- (a.z-b.z)*(a.z-b.z) );
+ return sqrt( (a.x-b.x)*(a.x-b.x) +
+ (a.z-b.z)*(a.z-b.z) );
}
//! Returns the normal vector to a plane
@@ -275,7 +265,7 @@ inline float DistanceToPlane(const Vector &a, const Vector &b, const Vector &c,
Vector n = NormalToPlane(a, b, c);
float d = -(n.x*a.x + n.y*a.y + n.z*a.z);
- return std::fabs(n.x*p.x + n.y*p.y + n.z*p.z + d);
+ return fabs(n.x*p.x + n.y*p.y + n.z*p.z + d);
}
//! Checks if two planes defined by three points are the same
@@ -286,9 +276,9 @@ inline bool IsSamePlane(const Vector (&plane1)[3], const Vector (&plane2)[3])
Vector n1 = NormalToPlane(plane1[0], plane1[1], plane1[2]);
Vector n2 = NormalToPlane(plane2[0], plane2[1], plane2[2]);
- if ( std::fabs(n1.x-n2.x) > 0.1f ||
- std::fabs(n1.y-n2.y) > 0.1f ||
- std::fabs(n1.z-n2.z) > 0.1f )
+ if ( fabs(n1.x-n2.x) > 0.1f ||
+ fabs(n1.y-n2.y) > 0.1f ||
+ fabs(n1.z-n2.z) > 0.1f )
return false;
float dist = DistanceToPlane(plane1[0], plane1[1], plane1[2], plane2[0]);
@@ -317,6 +307,107 @@ inline Vector SegmentPoint(const Vector &p1, const Vector &p2, float dist)
return p1 + (p2 - p1) * dist;
}
+//! Rotates a point around a center in space.
+/** \a center center of rotation
+ \a angleH,angleV rotation angles in radians (positive is counterclockwise (CCW) ) )
+ \a p the point
+ \returns the rotated point */
+inline Vector RotatePoint(const Vector &center, float angleH, float angleV, Vector p)
+{
+ Vector a, b;
+
+ p.x -= center.x;
+ p.y -= center.y;
+ p.z -= center.z;
+
+ b.x = p.x*cosf(angleH) - p.z*sinf(angleH);
+ b.y = p.z*sinf(angleV) + p.y*cosf(angleV);
+ b.z = p.x*sinf(angleH) + p.z*cosf(angleH);
+
+ float x = center.x+b.x;
+ float y = center.y+b.y;
+ float z = center.z+b.z;
+
+ return Vector(x, y, z);
+}
+
+//! Rotates a point around a center in space.
+/** \a center center of rotation
+ \a angleH,angleV rotation angles in radians (positive is counterclockwise (CCW) ) )
+ \a p the point
+ \returns the rotated point */
+inline Vector RotatePoint2(const Vector center, float angleH, float angleV, Vector p)
+{
+ Vector a, b;
+
+ p.x -= center.x;
+ p.y -= center.y;
+ p.z -= center.z;
+
+ a.x = p.x*cosf(angleH) - p.z*sinf(angleH);
+ a.y = p.y;
+ a.z = p.x*sinf(angleH) + p.z*cosf(angleH);
+
+ b.x = a.x;
+ b.y = a.z*sinf(angleV) + a.y*cosf(angleV);
+ b.z = a.z*cosf(angleV) - a.y*sinf(angleV);
+
+ float x = center.x+b.x;
+ float y = center.y+b.y;
+ float z = center.z+b.z;
+
+ return Vector(x, y, z);
+}
+
+//! Calculates the intersection "i" right "of" the plane "abc".
+inline bool Intersect(const Vector &a, const Vector &b, const Vector &c, const Vector &d, const Vector &e, Vector &i)
+{
+ float d1 = (d.x-a.x)*((b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z)) -
+ (d.y-a.y)*((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z)) +
+ (d.z-a.z)*((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
+
+ float d2 = (d.x-e.x)*((b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z)) -
+ (d.y-e.y)*((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z)) +
+ (d.z-e.z)*((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
+
+ if (d2 == 0)
+ return false;
+
+ i.x = d.x + d1/d2*(e.x-d.x);
+ i.y = d.y + d1/d2*(e.y-d.y);
+ i.z = d.z + d1/d2*(e.z-d.z);
+
+ return true;
+}
+
+//! Calculates the intersection of the straight line passing through p (x, z)
+/** Line is parallel to the y axis, with the plane abc. Returns p.y. */
+inline bool IntersectY(const Vector &a, const Vector &b, const Vector &c, Vector &p)
+{
+ float d = (b.x-a.x)*(c.z-a.z) - (c.x-a.x)*(b.z-a.z);
+ float d1 = (p.x-a.x)*(c.z-a.z) - (c.x-a.x)*(p.z-a.z);
+ float d2 = (b.x-a.x)*(p.z-a.z) - (p.x-a.x)*(b.z-a.z);
+
+ if (d == 0.0f)
+ return false;
+
+ p.y = a.y + d1/d*(b.y-a.y) + d2/d*(c.y-a.y);
+
+ return true;
+}
+
+//! Calculates the end point
+inline Vector LookatPoint(const Vector &eye, float angleH, float angleV, float length)
+{
+
+ Vector lookat = eye;
+ lookat.z += length;
+
+ RotatePoint(eye, angleH, angleV, lookat);
+
+ return lookat;
+}
+
/* @} */ // end of group
}; // namespace Math