Плоскость через 3 вершины

Автор Sprinter500, 10.04.11, 10:26:14

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Sprinter500

Здравствуйте ! Как программно построить плоскость через 3 произвольные точки с заданными координатами? В примере SDK  строится параллелипипед, и у него берется массив непонятно каких точек. Это не устраивает. Непонятно как вместо массива задать три произвольные точки с необходимыми координатами. Кто знает помогите пожалуйста. Желательно на языке Visual Basic

Sprinter500

Вот пример кода:
' Плоскость через три вершины
Sub constrPlane3Point()
  Dim part As Object                              ' интерфейс компонента
  Set part = iDocument3D.GetPart(pNew_Part)       ' новый компонент
 
  If Not part Is Nothing Then                     ' если компонент создан
    Dim entitySketch As Object                    ' интерфейс 3D-объекта
    Set entitySketch = part.NewEntity(o3d_sketch) ' создать новый эскиз
   
    If Not entitySketch Is Nothing Then           ' если 3D-объект создан
      Dim sketchDef As Object                     ' интерфейс свойств эскиза
      Set sketchDef = entitySketch.GetDefinition  ' берем у объекта его свойства
     
      If Not sketchDef Is Nothing Then            ' если интерфейс свойств есть
        Dim basePlane As Object                   ' интерфейс 3D-объекта
        Set basePlane = part.GetDefaultEntity(o3d_planeXOY) ' получим интерфейс базовой плоскости XOY
       
        If Not basePlane Is Nothing Then          ' плоскость получили
          sketchDef.SetPlane basePlane            ' установим плоскость XOY базовой для эскиза
          Set basePlane = Nothing                 ' освобождаем интерфейс
        End If                                    '
       
        entitySketch.Create                       ' создадим эскиз
        Dim sketchEdit As Object                  ' интерфейс редактора эскиза ksDocument2D
        Set sketchEdit = sketchDef.BeginEdit      ' открыть эскиз на редактирование
       
        If Not sketchEdit Is Nothing Then
          ' введем новый эскиз - квадрат
          sketchEdit.ksLineSeg 50, 50, -50, 50, 1
          sketchEdit.ksLineSeg 50, -50, -50, -50, 1
          sketchEdit.ksLineSeg 50, -50, 50, 50, 1
          sketchEdit.ksLineSeg -50, -50, -50, 50, 1
          sketchDef.EndEdit                       ' завершение редактирования эскиза
          Set sketchEdit = Nothing                ' освобождаем интерфейс
        End If
       
        Set sketchDef = Nothing                   ' освобождаем интерфейс
      End If                                      '
     
      Dim entityExtr As Object                    '
      Set entityExtr = part.NewEntity(o3d_baseExtrusion) '
      If Not entityExtr Is Nothing Then           '
        Dim extrusionDef As Object                ' интерфейс свойств базовой операции выдавливания
        Set extrusionDef = entityExtr.GetDefinition ' получаем интерфейс свойств базовой операции выдавливания
       
        If Not extrusionDef Is Nothing Then
          extrusionDef.directionType = dtNormal   ' направление выдавливания
          extrusionDef.SetSideParam True, etBlind, 20, 30, False
          extrusionDef.SetThinParam True, dtBoth, 10, 10 ' тонкая стенка в два направления
          extrusionDef.SetSketch entitySketch     ' эскиз операции выдавливания
          entityExtr.Create                       ' создать операцию
          Set extrusionDef = Nothing              ' освобождаем интерфейс
        End If
       
        Set entityExtr = Nothing                  ' освобождаем интерфейс
      End If
           
      Set entitySketch = Nothing                  ' освобождаем интерфейс
    End If                                        '
   
    Dim entityColl As Object                      ' интерфейс динамического массива 3D-объектов
    Set entityColl = part.EntityCollection(o3d_vertex) ' получаем массив вершин
    If Not entityColl Is Nothing And entityColl.GetCount > 2 Then
     
      ' Плоскость через три вершины
      Dim entityConstrPlane3Point As Object
      Set entityConstrPlane3Point = part.NewEntity(o3d_plane3Points)
      If Not entityConstrPlane3Point Is Nothing Then
        Dim constrPlane3Point As Object
        Set constrPlane3Point = entityConstrPlane3Point.GetDefinition
        If Not constrPlane3Point Is Nothing Then
          constrPlane3Point.SetPoint 1, entityColl.GetByIndex(0)
          constrPlane3Point.SetPoint 2, entityColl.GetByIndex(1)
          constrPlane3Point.SetPoint 3, entityColl.GetByIndex(2)
          entityConstrPlane3Point.Create
          Set constrPlane3Point = Nothing
        End If
        Set constrPlane3Point = Nothing
      End If
      iKompasObject.ksMessage "Плоскость через три вершины"
           
      Set entityColl = Nothing                    ' освобождаем интерфейс
    End If
   
    Set part = Nothing                            ' освобождаем интерфейс
  End If
 
End Sub

Slaviation

Пример скрипта, записанного с помощью КОМПАС-Макро, создания плоскости через три вершины в прилагаемой к примеру модели.

Sprinter500

Спасибо большое !!!! Вроде есть в Вашем коде задание точки по координатам. Чуть позже опробую :)

Sprinter500

Совместил два кода. Но не работает почему то :( Ничего не происходит абсолютно, ошибка не вылазит, но и не строит ничего. Как быть?

Sprinter500


333

Можно построить 3 точки см IPoint3D
и через них провести плоскость по трем точкам

Sprinter500

А можно поподробнее? Как эти точки построить?

Slaviation

Из VB-кода видно, что для трех вершин плоскости берутся первые три элемента коллекции вершин парта. Но тут нет гарантии того, что эти вершины из коллекции не лежат на одной прямой ( например см. рис. ). И в этом случае плоскость не построится. Возможно причина в этом. Измените код получения вершин для плоскости, чтобы они гарантированно не лежали на одной прямой. Для эксперимента предлагаю убрать из операции выдавливания тонкую стенку. В этом случае трех вершин на одной прямой не будет.

Через три произвольные точки можно провести только одну плоскость, через две точки только одну прямую, главное, чтобы точки не совпадали между собой, а для плоскости не лежали на одной прямой. Можно провести через две точки прямую и проверить третью на принадлежность прямой.

Sprinter500

Проблема не в том, чтобы узнать лежат ли эти точки на одной прямой или нет, а в том как построить эти точки, и по ним плоскость без построения подобных тел, показанных на рисунке. Тем более не ясно по какому принципу отбирались точки у этого объекта, ведь у него их гораздо больше чем 3.

Точки выбирались также, как и у Вас в примере первые три попавшиеся, которые вы не проверяете на предмет возможности построения через них плоскости.

Точки можно построить IPoint3D:
свойства
AssociationObject
Parameters
ParameterType
Symbol
X
Y
Z

Sprinter500

Я чайник в программировании. :) Подскажите пожалуйста как пользоваться этим IPoint3D. Есть образец кода, где используется IPoint3D ?

У меня кода нет так, что читайте в SDK

Sprinter500

В SDK кода нет, по крайней мере в SDK, от 9 версии Компаса, какая у меня и установлена   :`(


333

см
SDK\C++\Visualc\Step4_API7_3D\Step4_API7_3D.cpp

//-----------------------------------------------------------------------------
/**
  Создать точку
  \param doc - указатель на текущий документ
  \param x, y, z - координаты точки
  \return указатель на интерфейс точки
*/
//---
IPoint3DPtr CreatePoint( IKompasDocumentPtr & doc, double x, double y, double z )
{
  IPoint3DPtr newPoint = NULL;
 
  if ( doc )
  {
    // Получаем контейнер модельных объектов
    IModelContainerPtr modelCont( GetModelContainer(doc) );

    if ( modelCont )
    {
      // Получаем коллекцию точек
      IPoints3DPtr pointsColl( modelCont->GetPoints3D() );

      if ( pointsColl )
      {
        // Добавляем новую точку
        newPoint = pointsColl->Add();

        if ( newPoint )
        {
          // Задаем параметры точки
          newPoint->X = x;
          newPoint->Y = y;
          newPoint->Z = z;
          newPoint->Symbol = ksDotPoint;
          newPoint->ParameterType = ksPParamCoord;
          newPoint->Update();
        }
      }
    }
  }
  return newPoint;
}