Структуры данных для работы с объектами стереометрии
Листинг C++
#include <cstdio>
#include <cmath>
using namespace std;
#define sqr(x) ((x) * (x))
const double eps = 1e-9;
#define eq(a, b) (abs ((a) - (b)) <= eps)
// определитель второго порядка
double det (double a11, double a12, double a21, double a22)
{
return a11 * a22 - a12 * a21;
}
// точка в трёхмерном пространстве
class gpoint
{
public :
double x, y, z;
gpoint (double _x = 0, double _y = 0, double _z = 0) : x (_x), y (_y), z (_z) {};
};
// вектор в трёхмерном пространстве
class gvector
{
public :
double x, y, z;
gvector (double _x = 0, double _y = 0, double _z = 0) : x (_x), y (_y), z (_z) {};
gvector (gpoint a, gpoint b) : x (b.x - a.x), y (b.y - a.y), z (b.z - a.z) {};
// абсолютная длина вектора
double length ()
{
return sqrt (x * x + y * y + z * z);
}
// нормированный вектор
gvector norm ()
{
double d = length ();
if (! eq (d, 0))
return gvector (x / d, y / d, z / d);
else
return gvector (x, y, z);
}
// умножение вектора на число
gvector mul (double a)
{
return gvector (a * x, a * y, a * z);
}
};
// прямая в трёхмерном пространстве
class gline
{
public :
gpoint p;
gvector v;
gline () : p (gpoint (0, 0)), v (gvector (0, 0)) {};
gline (gpoint _p, gvector _v) : p (_p), v (_v) {};
gline (gpoint a, gpoint b) : p (a), v (gvector (a, b)) {};
// лежит ли точка на прямой
bool in_line (gpoint t)
{
return eq ((t.x - p.x) * v.y, (t.y - p.y) * v.x) &&
eq ((t.x - p.x) * v.z, (t.z - p.z) * v.x) &&
eq ((t.y - p.y) * v.z, (t.z - p.z) * v.y);
}
};
// плоскость в трёхмерном пространстве
class gplane
{
public :
double A, B, C, D;
gplane (double _A = 0, double _B = 0, double _C = 0, double _D = 0) : A (_A), B (_B), C (_C), D (_D) {};
gplane (gpoint a, gpoint b, gpoint c)
{
gvector N = vector_mul (gvector (a, b), gvector (a, c));
A = N.x;
B = N.y;
C = N.z;
D = - A * a.x - B * a.y - C * a.z;
}
// знак точки относительно плоскости
int sign (gpoint a)
{
double s = A * a.x + B * a.y + C * a.z + D;
if (eq (s, 0)) return 0;
if (s < 0) return - 1;
return 1;
}
};
Создано 21:59
07.11.2009
По всем вопросам обращаться: rumterg@gmail.com