|
Класс Segment3d предназначен для представления отрезка в трёхмерном пространстве:
class Segment3d
{
public:
Vector3d a, b;
Segment3d () {}
Segment3d ( const Vector3d & va, const Vector3d & vb ) : a(va), b(vb) {}
double qdis ( const Vector3d & p ) const; // квадрат расстояния до точки p
double qmod () const { return ::qmod ( b - a ); } // квадрат длины отрезка
};
inline bool operator != ( const Segment3d & s1, const Segment3d & s2 )
{
return ( s1.a != s2.a ) || ( s1.b != s2.b );
}
inline bool operator == ( const Segment3d & s1, const Segment3d & s2 )
{
return ( s1.a == s2.a ) && ( s1.b == s2.b );
}
inline double norm1 ( const Segment3d & s ) { return norm1 ( s.b - s.a ); } // единичная норма
inline double norm2 ( const Segment3d & s ) { return norm2 ( s.b - s.a ); } // квадратичная норма
inline double normU ( const Segment3d & s ) { return normU ( s.b - s.a ); } // бесконечная норма
Класс Line3d предназначен для представления прямой в трёхмерном пространстве.
Здесь dir - это направление прямой, а point - точка через которую проходит прямая. Функции-члены project и qdis предполают, что 2-норма вектора dir равна единице:
class Line3d
{
public:
Vector3d dir;
Vector3d point;
Line3d () {}
Line3d ( const Vector3d & a, const Vector3d & b ) : dir(a), point(b) {}
Vector3d project ( const Vector3d & p ) const // проекция точки p на прямую
{
return point + dir * ( dir * ( p - point ) );
}
double qdis ( const Vector3d & p ) const // квадрат расстояния до точки p
{
return qmod ( p - project ( p ) );
}
};
Класс Plane3d предназначен для представления плоскости в трёхмерном пространстве. Вектор norm является нормалью к плоскости ( обычно единичной длины ), а переменная dist - расстоянием от плоскости до центра координат с учётом знака. Плоскость делит пространство на два полупространства, а нормаль указывает какое из них является верхним по отношению к плоскости, а какое нижним ( считаем, что нормаль направлена вверх ). Эти полупространства можно назвать также положительным и отрицательным. Соответственно расстояние от произвольной точки из верхнего полупространства до плоскости будем считать положительным, а из нижнего отрицательным. Оператор % вычисляет такое расстояние. Для всех точек плоскости должно выполняться равенство: norm * point + dist = 0. У класса три конструктора. Первый ничего не делает. Второй строит плоскость по трём точкам с учётом направления обхода. Третий строит плоскость по нормали и расстоянию до центра координат. Оператор унарный минус возвращает плоскость, которая совпадает с исходной, но для которой верх и низ поменялись местами. Операторы += и -= сдвигают плоскость в одну или другую сторону на указанный вектор. Функция-член project возвращает точку на плоскости ближайшую к заданной. Функции-члены mirror возвращают точку или плоскость отражённые относительно this. По поводу операторов ==, != и *= можно сказать то же, что и для векторов. class Plane3d
{
template <typename T> void mul ( const T & t, ... )
{
*this = t ( *this );
}
template <typename T> void mul ( const T & t, double d )
{
dist *= d;
}
public:
Vector3d norm;
double dist;
Plane3d () {}
Plane3d ( const Vector3d &, const Vector3d &, const Vector3d & );
Plane3d ( const Vector3d & v, const double & d ) : norm ( v ),
dist ( d ) {}
double operator % ( const Vector3d & v ) const
{
return norm.x * v.x + norm.y * v.y + norm.z * v.z + dist;
}
Plane3d operator - () const
{
return Plane3d ( - norm, - dist );
}
template <typename T> Plane3d & operator *= ( const T & t )
{
mul ( t, t );
return *this;
}
Plane3d & operator += ( const Vector3d & p )
{
dist -= norm * p;
return *this;
}
Plane3d & operator -= ( const Vector3d & p )
{
dist += norm * p;
return *this;
}
Vector3d project ( const Vector3d & v ) const; // Проекция точки на плоскость
Vector3d mirror ( const Vector3d & v ) const; // Отражение точки
Plane3d mirror ( const Plane3d & p ) const; // Отражение плоскости
};
inline bool operator == ( const Plane3d & p1, const Plane3d & p2 )
{
return p1.norm == p2.norm && p1.dist == p2.dist;
}
inline bool operator != ( const Plane3d & p1, const Plane3d & p2 )
{
return p1.norm != p2.norm || p1.dist != p2.dist;
}
Класс Sphere3d предназначен для представления сферы: class Sphere3d
{
public:
double r; // радиус
Vector3d o; // центр
Sphere3d () {}
Sphere3d ( double a, const Vector3d & b ) : r ( a ), o ( b ) {}
double volume () const { return 4./3. * M_PI * r * r * r; } // объём
};
Класс Ellipse3d предназначен для представления эллипсоидов. Функция-член getAffin3d возвращает аффинное преобразование, которое отображает единичную сферу в данный эллипсоид: class Ellipsoid3d
{
public:
double a, b, c; // полуоси
Spin3d spin; // поворот
Vector3d o; // центр
Affin3d getAffin3d() const
{
LinTran3d t ( spin );
t.x.x *= a; t.x.y *= b; t.x.z *= c;
t.y.x *= a; t.y.y *= b; t.y.z *= c;
t.z.x *= a; t.z.y *= b; t.z.z *= c;
return Affin3d ( t, o );
}
double volume () const { return 4./3. * M_PI * a * b * c; } // объём
};
Класс Parallelepiped3d предназначен для представления параллелепипедов:
class Parallelepiped3d
{
public:
double a, b, c; // полуоси
Spin3d spin; // поворот
Vector3d o; // центр
double volume () const { return 8 * a * b * c; } // объём
};
Класс Cylinder3d предназначен для представления цилиндров: class Cylinder3d
{
public:
double r, h; // радиус и половина высоты
Spin3d spin; // поворот
Vector3d o; // центр
double volume () const { return M_2PI * r * r * h; } // объём
};
Класс Cone3d предназначен для представления конусов: class Cone3d
{
public:
double r, h; // радиус основания и половина высоты
Spin3d spin; // поворот
Vector3d o; // центр
double volume () const { return M_2PI/3 * r * r * h; } // объём
};
Примеры использования всех этих классов можно посмотреть в приложении DEMO. Описание класса Vector3d находится здесь.Описание классов Spin3d и Conform3d находится здесь. Исходники находятся в файлах vector3d.h, vector3d.cpp. Наверх
|