Structs continued
parent
ea442a887d
commit
f67a62fb28
|
@ -0,0 +1,31 @@
|
|||
// * This file is part of the COLOBOT source code
|
||||
// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have received a copy of the GNU General Public License
|
||||
// * along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
/** @defgroup MathAllModule math/all.h
|
||||
Includes all other math module headers.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* @{ */ // start of group
|
||||
|
||||
#include "const.h"
|
||||
#include "func.h"
|
||||
#include "point.h"
|
||||
#include "vector.h"
|
||||
#include "matrix.h"
|
||||
|
||||
/* @} */ // end of group
|
|
@ -71,7 +71,7 @@ struct Matrix
|
|||
|
||||
//! Creates the matrix from 1D array
|
||||
/** \a m matrix values in column-major order */
|
||||
inline Matrix(const float (&m)[16])
|
||||
inline explicit Matrix(const float (&m)[16])
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
this->m[i] = m[i];
|
||||
|
@ -80,7 +80,7 @@ struct Matrix
|
|||
//! Creates the matrix from 2D array
|
||||
/** The array's first index is row, second is column.
|
||||
\a m array with values */
|
||||
inline Matrix(const float (&m)[4][4])
|
||||
inline explicit Matrix(const float (&m)[4][4])
|
||||
{
|
||||
for (int c = 0; c < 4; ++c)
|
||||
{
|
||||
|
@ -547,7 +547,21 @@ struct Matrix
|
|||
temp.LoadRotationY(angle.y);
|
||||
this->Multiply(temp);
|
||||
}
|
||||
};
|
||||
|
||||
}; // struct Matrix
|
||||
|
||||
//! Checks if two matrices are equal within given \a tolerance
|
||||
inline bool MatricesEqual(const Matrix &m1, const Matrix &m2,
|
||||
float tolerance = TOLERANCE)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
if (! IsEqual(m1.m[i], m2.m[i], tolerance))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Convenience function for getting transposed matrix
|
||||
inline Matrix Transpose(const Matrix &m)
|
||||
|
@ -592,17 +606,22 @@ inline Vector MatrixVectorMultiply(const Matrix &m, const Vector &v)
|
|||
return Vector(x, y, z);
|
||||
}
|
||||
|
||||
//! Checks if two matrices are equal within given \a tolerance
|
||||
inline bool MatricesEqual(const Matrix &m1, const Matrix &m2,
|
||||
float tolerance = TOLERANCE)
|
||||
//! Calculation point of view to look at a center two angles and a distance
|
||||
inline Vector RotateView(const Vector ¢er, float angleH, float angleV, float dist)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
if (! IsEqual(m1.m[i], m2.m[i], tolerance))
|
||||
return false;
|
||||
}
|
||||
Matrix mat1, mat2, mat;
|
||||
|
||||
return true;
|
||||
mat1.LoadRotationZ(-angleV);
|
||||
mat2.LoadRotationY(-angleH);
|
||||
mat = MultiplyMatrices(mat1, mat2);
|
||||
|
||||
Vector eye;
|
||||
eye.x = 0.0f+dist;
|
||||
eye.y = 0.0f;
|
||||
eye.z = 0.0f;
|
||||
eye = MatrixVectorMultiply(mat, eye);
|
||||
|
||||
return eye + center;
|
||||
}
|
||||
|
||||
/* @} */ // end of group
|
||||
|
|
160
src/math/point.h
160
src/math/point.h
|
@ -26,17 +26,6 @@
|
|||
#include <cmath>
|
||||
|
||||
|
||||
/* TODO
|
||||
|
||||
FPOINT RotatePoint(FPOINT center, float angle, FPOINT p);
|
||||
FPOINT RotatePoint(float angle, FPOINT p);
|
||||
FPOINT RotatePoint(float angle, float dist);
|
||||
void RotatePoint(float cx, float cy, float angle, float &px, float &py);
|
||||
|
||||
float RotateAngle(FPOINT center, FPOINT p1, FPOINT p2);
|
||||
|
||||
*/
|
||||
|
||||
// Math module namespace
|
||||
namespace Math
|
||||
{
|
||||
|
@ -66,7 +55,7 @@ struct Point
|
|||
}
|
||||
|
||||
//! Constructs a point from given coords: (x,y)
|
||||
inline Point(float x, float y)
|
||||
inline explicit Point(float x, float y)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
|
@ -81,9 +70,85 @@ struct Point
|
|||
//! Returns the distance from (0,0) to the point (x,y)
|
||||
inline float Length()
|
||||
{
|
||||
return std::sqrt(x*x + y*y);
|
||||
return sqrt(x*x + y*y);
|
||||
}
|
||||
};
|
||||
|
||||
//! Returns the inverted point
|
||||
inline Point operator-() const
|
||||
{
|
||||
return Point(-x, -y);
|
||||
}
|
||||
|
||||
//! Adds the given point
|
||||
inline const Point& operator+=(const Point &right)
|
||||
{
|
||||
x += right.x;
|
||||
y += right.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Adds two points
|
||||
inline friend const Point operator+(const Point &left, const Point &right)
|
||||
{
|
||||
return Point(left.x + right.x, left.y + right.y);
|
||||
}
|
||||
|
||||
//! Subtracts the given vector
|
||||
inline const Point& operator-=(const Point &right)
|
||||
{
|
||||
x -= right.x;
|
||||
y -= right.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Subtracts two points
|
||||
inline friend const Point operator-(const Point &left, const Point &right)
|
||||
{
|
||||
return Point(left.x - right.x, left.y - right.y);
|
||||
}
|
||||
|
||||
//! Multiplies by given scalar
|
||||
inline const Point& operator*=(const float &right)
|
||||
{
|
||||
x *= right;
|
||||
y *= right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Multiplies point by scalar
|
||||
inline friend const Point operator*(const float &left, const Point &right)
|
||||
{
|
||||
return Point(left * right.x, left * right.y);
|
||||
}
|
||||
|
||||
//! Multiplies point by scalar
|
||||
inline friend const Point operator*(const Point &left, const float &right)
|
||||
{
|
||||
return Point(left.x * right, left.y * right);
|
||||
}
|
||||
|
||||
//! Divides by given scalar
|
||||
inline const Point& operator/=(const float &right)
|
||||
{
|
||||
x /= right;
|
||||
y /= right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Divides point by scalar
|
||||
inline friend const Point operator/(const Point &left, const float &right)
|
||||
{
|
||||
return Point(left.x / right, left.y / right);
|
||||
}
|
||||
|
||||
}; // struct Point
|
||||
|
||||
|
||||
//! Checks if two vectors are equal within given \a tolerance
|
||||
inline bool PointsEqual(const Point &a, const Point &b, float tolerance = TOLERANCE)
|
||||
{
|
||||
return IsEqual(a.x, b.x, tolerance) && IsEqual(a.y, b.y, tolerance);
|
||||
}
|
||||
|
||||
//! Permutes two points
|
||||
inline void Swap(Point &a, Point &b)
|
||||
|
@ -161,6 +226,73 @@ inline bool IsInsideTriangle(Point a, Point b, Point c, const Point &p)
|
|||
return true;
|
||||
}
|
||||
|
||||
//! Rotates a point around a center
|
||||
/** \a center center of rotation
|
||||
\a angle angle is in radians (positive is counterclockwise (CCW) )
|
||||
\a p the point */
|
||||
inline Point RotatePoint(const Point ¢er, float angle, const Point &p)
|
||||
{
|
||||
Point a;
|
||||
a.x = p.x-center.x;
|
||||
a.y = p.y-center.y;
|
||||
|
||||
Point b;
|
||||
b.x = a.x*cosf(angle) - a.y*sinf(angle);
|
||||
b.y = a.x*sinf(angle) + a.y*cosf(angle);
|
||||
|
||||
b.x += center.x;
|
||||
b.y += center.y;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
//! Rotates a point around the origin (0,0)
|
||||
/** \a angle angle in radians (positive is counterclockwise (CCW) )
|
||||
\a p the point */
|
||||
inline Point RotatePoint(float angle, const Point &p)
|
||||
{
|
||||
float x = p.x*cosf(angle) - p.y*sinf(angle);
|
||||
float y = p.x*sinf(angle) + p.y*cosf(angle);
|
||||
|
||||
return Point(x, y);
|
||||
}
|
||||
|
||||
//! Rotates a vector (dist, 0).
|
||||
/** \a angle angle is in radians (positive is counterclockwise (CCW) )
|
||||
\a dist distance to origin */
|
||||
inline Point RotatePoint(float angle, float dist)
|
||||
{
|
||||
float x = dist*cosf(angle);
|
||||
float y = dist*sinf(angle);
|
||||
|
||||
return Point(x, y);
|
||||
}
|
||||
|
||||
//! Calculates the angle between two points and one center
|
||||
/** \a center the center point
|
||||
\a p1,p2 the two points
|
||||
\returns The angle in radians (positive is counterclockwise (CCW) ) */
|
||||
inline float RotateAngle(const Point ¢er, const Point &p1, const Point &p2)
|
||||
{
|
||||
if (PointsEqual(p1, center))
|
||||
return 0;
|
||||
|
||||
if (PointsEqual(p2, center))
|
||||
return 0;
|
||||
|
||||
float a1 = asinf((p1.y - center.y) / Distance(p1, center));
|
||||
float a2 = asinf((p2.y - center.y) / Distance(p2, center));
|
||||
|
||||
if (p1.x < center.x) a1 = PI - a1;
|
||||
if (p2.x < center.x) a2 = PI - a2;
|
||||
|
||||
float a = a2 - a1;
|
||||
if (a < 0)
|
||||
a += PI_MUL_2;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/* @} */ // end of group
|
||||
|
||||
}; // namespace Math
|
||||
|
|
|
@ -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 ¢er, 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
|
||||
|
|
Loading…
Reference in New Issue