| • Отрезок 
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; // Проекция точки на плоскость    
    Segment3d project ( const Segment3d & s ) const // Проекция отрезка на плоскость
    {
        return Segment3d ( project ( s.a ), project ( s.b ) );
    }
    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 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 Ellipse3d
{
public:
    Vector3d o;  // центр
    double a, b; // полуоси
    Spin3d spin; // поворот
    Ellipse3d () {}
    Ellipse3d ( const Vector3d & o1, double a1, double b1 ) : o ( o1 ), a ( a1 ), b ( b1 ) {}
    Vector3d getNorm () const
    {
        return spin.rotZ();
    }
    double getArea () const;
    double getPerimeter () const;
    Ellipse3d & operator *= ( const Conform3d & c )
    {
        o *= c; a *= c.magn; b *= c.magn; spin = c.spin * spin; return *this;
    }
    Ellipse3d & operator *= ( const Spin3d & s )
    {
        o *= Ortho3d ( s ); spin = s * spin; return *this;
    }
    Ellipse3d & operator *= ( const double & d )
    {
        o *= d; a *= d; b *= d; return *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 ) {}
    Vector3d getNormal () const
    {
        return ( ( a - b ) % ( b - c ) ).setNorm2();
    }
    double getArea () const // Площадь поверхности треугольника с двух сторон
    {
        return norm2 ( ( a - b ) % ( b - c ) );
    }
};
• Прямоугольник 
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 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;
};
• Тетраэдр 
class Tetrahedron
{
public:
    Vector3d a, b, c, d;
    Tetrahedron () {}
};
 • Прямоугольный параллелепипед 
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;
};
 Функции вычисляющие расстояния от точки до некоторых из этих фигур находятся здесь. Примеры использования всех этих классов можно посмотреть в приложении DEMO.Описание класса Vector3d находится здесь. Описание классов Spin3d и Conform3d находится здесь. Исходники находятся в файлах vector3d.h, vector3d.cpp.Наверх 
 |