• Отрезок class Segment3d { public: Vector3d a, b; Segment3d () {} Segment3d ( const Vector3d & va, const Vector3d & vb ) : a(va), b(vb) {} Def<Vector3d> project ( const Vector3d & p ) const; // проекция точки на отрезок Vector3d nearPoint ( const Vector3d & p ) const; // ближайшая точка отрезка к данной double qdis ( const Vector3d & p ) const // квадрат расстояния до точки p { return ::qmod ( p - nearPoint ( p ) ); } double qmod () const { return ::qmod ( b - a ); } // квадрат длины отрезка template <typename T> Segment3d & operator *= ( const T & t ) { a *= t, b *= t; return * this; } }; 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 ); } // бесконечная норма• Прямая 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 ) ); } };Здесь dir - это направление прямой, а point - точка через которую проходит прямая. Функции-члены project и qdis предполают, что 2-норма вектора dir равна единице. • Плоскость 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; } Plane3d & setNorm2 ( double p = 1 ) { if ( !!norm ) { double t = norm2 ( norm ); t = p / t; norm *= t; dist *= t; } 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; } inline double operator % ( const Vector3d & a, const Plane3d & b ) { return b.norm.x * a.x + b.norm.y * a.y + b.norm.z * a.z + b.dist; }Вектор norm является нормалью к плоскости ( обычно единичной длины ), а переменная dist - расстоянием от плоскости до центра координат с учётом знака. Плоскость делит пространство на два полупространства, а нормаль указывает какое из них является верхним по отношению к плоскости, а какое нижним ( считаем, что нормаль направлена вверх ). Эти полупространства можно назвать также положительным и отрицательным. Соответственно расстояние от произвольной точки из верхнего полупространства до плоскости будем считать положительным, а из нижнего отрицательным. Оператор % вычисляет такое расстояние. Для всех точек плоскости должно выполняться равенство: norm * point + dist = 0. У класса три конструктора. Первый ничего не делает. Второй строит плоскость по трём точкам с учётом направления обхода. Третий строит плоскость по нормали и расстоянию до центра координат. Оператор унарный минус возвращает плоскость, которая совпадает с исходной, но для которой верх и низ поменялись местами. Операторы += и -= сдвигают плоскость в одну или другую сторону на указанный вектор. Функция-член setNorm2 устанавливает квадратичную норму для вектора norm. Функция-член project возвращает точку на плоскости ближайшую к заданной. Функции-члены mirror возвращают точку или плоскость отражённые относительно this. По поводу операторов ==, != и *= можно сказать то же, что и для векторов. • Треугольник class Triangle3d { public: Vector3d a, b, c; Triangle3d () {} Triangle3d ( const Vector3d & pa, const Vector3d & pb, const Vector3d & pc ) : a ( pa ), b ( pb ), c ( pc ) {} double getArea () const // Площадь поверхности треугольника с двух сторон { return norm2 ( ( a - b ) % ( b - c ) ); } }; • Круг class Circle3d { public: Vector3d o; // центр double r; // радиус Spin3d spin;// поворот Circle3d () {} Circle3d ( const Vector3d & a, double b ) : o ( a ), r ( b ) {} Circle3d & operator *= ( const Conform3d & c ) { o *= c; r *= c.magn; spin = c.spin * spin; return *this; } Circle3d & operator *= ( const Spin3d & s ) { o *= Ortho3d ( s ); spin = s * spin; return *this; } Circle3d & operator *= ( const double & d ) { o *= d; r *= d; return *this; } }; • Прямоугольник class Rectangle3d { public: Vector3d o; // центр double a, b; // полуоси Spin3d spin; // поворот Rectangle3d () {} Rectangle3d ( const Vector3d & o1, double a1, double b1 ) : o ( o1 ), a ( a1 ), b ( b1 ) {} void getVerts ( Vector3d vert[4] ) const; Vector3d getNorm () const { return spin.rotZ(); } Rectangle3d & operator *= ( const Conform3d & c ) { o *= c; a *= c.magn; b *= c.magn; spin = c.spin * spin; return *this; } Rectangle3d & operator *= ( const Spin3d & s ) { o *= Ortho3d ( s ); spin = s * spin; return *this; } Rectangle3d & operator *= ( const double & d ) { o *= d; a *= d; b *= d; return *this; } };• Ромб class Rhombus3d { public: Vector3d o; // центр double a, b; // полуоси Spin3d spin; // поворот Rhombus3d () {} Rhombus3d ( const Vector3d & o1, double a1, double b1 ) : o ( o1 ), a ( a1 ), b ( b1 ) {} void getVerts ( Vector3d vert[4] ) const; Vector3d getNorm () const { return spin.rotZ(); } double getArea () const { return 2 * a * b; } double getPerimeter () const; Rhombus3d & operator *= ( const Conform3d & c ) { o *= c; a *= c.magn; b *= c.magn; spin = c.spin * spin; return *this; } Rhombus3d & operator *= ( const Spin3d & s ) { o *= Ortho3d ( s ); spin = s * spin; return *this; } Rhombus3d & operator *= ( const double & d ) { o *= d; a *= d; b *= d; return *this; } };• Параллелограмм class Parallelogram3d { Vector3d o, a, b; public: Parallelogram3d () {} Parallelogram3d ( const Vector3d & v1, const Vector3d & v2, const Vector3d & v3 ) : o ( v2 ), a ( v3 - v2 ), b ( v1 - v2 ) {} void getVerts ( Vector3d vert[4] ) const { vert[0] = o + b; vert[1] = o; vert[2] = o + a; vert[3] = o + a + b; } Vector3d getNorm () const { return ( a % b ).setNorm2(); } double getPerimeter () const { return 2 * ( norm2 ( a ) + norm2 ( b ) ); } Parallelogram3d & operator *= ( const Conform3d & c ) { Similar3d sim ( c ); o *= sim; a *= sim.setTrans ( null3d ); b *= sim; return *this; } }; • Шар class Sphere3d { public: double r; // радиус Vector3d o; // центр Sphere3d () {} Sphere3d ( double a, const Vector3d & b ) : r ( a ), o ( b ) {} double getArea () const; }; • Эллипсоид 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 getArea () const; };Функция-член getAffin3d возвращает аффинное преобразование, которое отображает единичную сферу в данный эллипсоид: • Прямоугольный параллелепипед class Cuboid3d { 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 getArea () const; }; • Цилиндр class Cylinder3d { public: double r, h; // радиус и половина высоты Spin3d spin; // поворот Vector3d o; // центр double getArea () const; }; • Конус class Cone3d { public: double r, h; // радиус основания и половина высоты Spin3d spin; // поворот Vector3d o; // центр double getArea () const; }; Функции вычисляющие расстояния от точки до некоторых из этих фигур находятся здесь. Примеры использования всех этих классов можно посмотреть в приложении DEMO. Описание класса Vector3d находится здесь.Описание классов Spin3d и Conform3d находится здесь. Исходники находятся в файлах vector3d.h, vector3d.cpp. Наверх
|