RU: Point

Геометрические примитивы

Точка

Классы, связанные с понятием "точка"

В OpenCascade с понятием "точка" связаны следующие классы:

  • Класс gp_XYZ описывает тройку чисел чисел $(x, y, z)$.
  • Класс gp_Pnt описывает точку как математическое понятие.
  • Класс TopoDS_Vertex описывает точку в пространстве как элемент топологии, т.е. как конструктивный элемент при построении тела.
  • Класс Geom_CartesianPoint описывает точку в пространстве как элемент построения геометрических фигур
  • Класс AIS_Point описывает точку в пространстве как отображаемый элемент

Несколько примеров

Рассмотрим несколько примеров использования объектов указанных классов.

Чтобы создать точку с координатами $(1., 2., 3.)$ достаточно записать

    gp_Pnt gpPoint(1.,2.,3.);

Можно вначале создать точку, а потом задать ее координаты:
    gp_Pnt gpPoint;
    gpPoint.SetCoord(1.,2.,3.);

Или задать координаты по отдельности
    gp_Pnt gpPoint;
    gpPoint.SetX(1.);    gpPoint.SetY(2.);   gpPoint.SetZ(3.);

Координаты можно задавать и по номеру. Обратите внимание на то, что они нумеруются с единицы (а не с нуля)
    gp_Pnt gpPoint;
    gpPoint.SetCoord(1,1.);    gpPoint.SetCoord(2,2.);   gpPoint.SetCoord(3,3.);

Отметим, что для точек не определены такие операции как сложение и произведение. Точка не есть радиус-вектор. Но точки можно проверять на совпадение (LinearTolerance — погрешность)

     Standard_Boolean IsEqual( const gp_Pnt& Other, const Standard_Real LinearTolerance   )

можно измерять расстояние до другой точки
// Расстояние от данной точки до точки Other
    Standard_Real Distance(const gp_Pnt& Other)
// Квадрат расстояния от данной точки до точки Other
    Standard_Real SquareDistance(const gp_Pnt& Other)

а также можно вычислить центр тяжести (барицентр) данной точки и точки P, т.е. выражение (Alpha*this + Beta*P) / (Alpha + Beta)
    void BaryCenter( const Standard_Real Alpha, const gp_Pnt& P, const Standard_Real Beta)

Преобразования

Рассмотрим действие преобразований применительно к точке. Они составляют основу преобразований любых объектов.

Переместим точку на вектор $(1, 1, 1)$.

    gpPoint.Translate(gp_Vec(1.,1.,1.));

Теперь ее координаты $(2, 3, 4)$. Отразим эту точку относительно точки $(2, 2, 2)$. Отражение точки $\mathbf{r}$ относительно точки $\mathbf{r}_O$ есть преобразование $\mathbf{r}'-\mathbf{r}_O=-(\mathbf{r}-\mathbf{r}_O)$ или $\mathbf{r}'=-\mathbf{r}+2\mathbf{r}_O$, так что после преобразования
    gpPoint.Mirror(gp_Pnt(2.,2.,2.));

координаты получат значения $(2, 1, 0)$. Отразим эту точку относительно оси с началом $(0, 0, 0)$ (эта точка может быть получена вызовом gp::Origin() ) и направлением $(1, 1, 1)$:
    gp_Dir dir(1.,1.,1.);
    gpPoint.Mirror(gp_Ax1(gp::Origin(),dir));

Отражение точки $\mathbf{r}$ относительно оси с началом $\mathbf{r}_O$ и направлением $\mathbf{e}$ есть преобразование $\mathbf{r}'=-\mathbf{r}+2\{\mathbf{r}_O+(\mathbf{r}-\mathbf{r}_O,\mathbf{e})\mathbf{e}\}$, так что после преобразования координаты имеют значения $(0, 1, 2)$.

Выполним теперь отражение точки $(0, 1, 2)$ относительно плоскости, содержащей ось $z$ и делящей пополам угол между осями $x$ и $y$. Напомним, что преобразование отражения относительно плоскости, содержащей точку $\mathbf{r}_O$ и имеющей нормаль $\mathbf{N}$ выглядит так: $\mathbf{r}'=\mathbf{r}-2(\mathbf{r}-\mathbf{r}_O,\mathbf{N})\mathbf{N}$:

    gp_Dir dir_x(0.,0.,1.);
    gp_Dir dir_z(-1.,1.,0.);
    gp_Ax2 plane(gp::Origin(),dir_z,dir_x);
    gpPoint.Mirror(plane);

Новое положение точки есть $(1, 0, 2)$.

Как нарисовать точку

Чтобы нарисовать точку, нужно создать объект класса AIS_Point. Сделать это можно по-разному, как показано в следующем примере:

// Рисуем оси координат (для наглядности)
    Handle(AIS_Trihedron) aTrihedron;
    Handle(Geom_Axis2Placement) aTrihedronAxis=new Geom_Axis2Placement(gp::XOY());
    aTrihedron = new AIS_Trihedron(aTrihedronAxis);
    myAISContext->Display(aTrihedron);
//
// Точка
    gp_Pnt point;
    point.SetCoord(0.,100.,100.);    // по умолчанию таковы размеры области экрана
    Handle(Geom_CartesianPoint) geomPoint = new Geom_CartesianPoint(point);
    Handle(AIS_Point) AISPoint = new AIS_Point(geomPoint);
    AISPoint->SetMarker (Aspect_TOM_BALL );                //  Тип маркера
    myAISContext->SetColor(AISPoint,Quantity_NOC_GREEN);    //  Цвет
    myAISContext->Display(AISPoint);
//
// Вершина
    TopoDS_Vertex vrtx = BRepBuilderAPI_MakeVertex(gp_Pnt(100.,0.,100.));
    Handle(AIS_Shape) shape = new AIS_Shape(vrtx);
    myAISContext->Display(shape,Standard_False);

Вот результат выполнения этого участка программы:

OCC_point02.JPG

Свойства множества точек

Методы класса GProp_PEquation позволяют анализировать взаимное расположение множества точек, а именно

  • совпадают ли они
  • лежат ли они на одной прямой
  • лежат ли они в одной плоскости
  • получить минимальный параллелепипед, содержащий точки.

Конструктору класса передается массив точек и точность, с которой определяются свойства этого массива:

   GProp_PEquation(const TColgp_Array1OfPnt& Pnts,const Standard_Real Tol)

Проверка совпадения
// Процедура возвращает true если точки совпадают с заданной точностью
   Standard_Boolean IsPoint()
//
// Для совпадающих точек процедура возвращает среднюю
   gp_Pnt Point()

Проверка принадлежности одной прямой

// Процедура возвращает true если точки с заданной точностью лежат на одной прямой
   Standard_Boolean IsLinear()
//
// Для точек, лежащих на одной прямой процедура возвращает уравнение этой прямой
   gp_Lin Line()

Проверка принадлежности одной плоскости

// Процедура возвращает true если точки с заданной точностью лежат в одной плоскости
   Standard_Boolean IsPlanar()
//
// Для точек, лежащих в одной плоскости процедура возвращает уравнение этой плоскости
   gp_Pln Plane()

Наконец
// Процедура возвращает true если точки с заданной точностью лежат в области пространства
// (т.е. не реализуется ни одна из предыдущих ситуаций)
   Standard_Boolean IsSpace()
//
// Для точек, лежащих в области пространства процедура строит минимальный параллелепипед
// (со сторонами, параллельными осям координат), содержащий все точки
// P -- точка центра тяжести
// V1, V2, V3 -- стороны параллелипипеда
   void Box(gp_Pnt& P, gp_Vec& V1, gp_Vec& V2, gp_Vec& V3)

Расстояние и перпендикуляр

  • Расстояние до другой точки вычисляется процедурой
// Расстояние от данной точки до точки Other
    Standard_Real gp_Pnt::Distance(const gp_Pnt& Other)
  • Расстояние до прямой и перпендикуляр, опущенный из точки на прямую, см. Прямая.
  • Расстояние до кривой и перпендикуляр, опущенный из точки на кривую, см
  • Расстояние до плоскости и перпендикуляр, опущенный из точки на плоскость, см
  • Расстояние до поверхности и перпендикуляр, опущенный из точки на поверхность, см