Проекция полилинии на 3д поверхность

Автор Тема: Проекция полилинии на 3д поверхность  (Прочитано 18086 раз)

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

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
а вот сам алгоритм взял первый который нашел, т.к. про триангуляцию ничего не знаю.
Может есть варианты по практичней? Данных алгоритм периодически либо не захватывает все предложенные вершины, либо строит модель с пересекающимися ребрами.
Я когда-то использовал этот алгоритм: http://paulbourke.net/papers/triangulate/cpp.zip
И вообще можешь глянуть сюда: http://paulbourke.net/papers/triangulate/
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Николай Горлов

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
вот, поковырялся у себя в тестовых функциях, думаю пригодится )))
Код - C++ [Выбрать]
  1. Acad::ErrorStatus FindTrianglePt(AcGePoint3d vertex1, AcGePoint3d vertex2, AcGePoint3d vertex3, AcGePoint3d &resPt)
  2. {
  3.         Acad::ErrorStatus es = Acad::eAmbiguousInput;
  4.         double minZ = vertex1.z, maxZ = vertex1.z;
  5.         if (minZ > vertex2.z) minZ = vertex2.z;
  6.         if (minZ > vertex3.z) minZ = vertex3.z;
  7.         if (maxZ < vertex2.z) maxZ = vertex2.z;
  8.         if (maxZ < vertex3.z) maxZ = vertex3.z;
  9.  
  10.         AcGeVector3d vecU(vertex2.asVector()-vertex1.asVector());
  11.         AcGeVector3d vecV(vertex3.asVector()-vertex1.asVector());
  12.         AcGePlane plane(vertex1, vecU, vecV); // плоскость по трем точкам треугольника
  13.         AcGeLineSeg3d line (AcGePoint3d(resPt.x,resPt.y,minZ), AcGePoint3d(resPt.x,resPt.y,maxZ));//линия для поиска пересечений с плоскостью
  14.         AcGePoint3d resultPoint;//временная точка, чтоб не поганить основную, если ничего не нужно
  15.         if (plane.intersectWith(line, resultPoint) == Adesk::kTrue)
  16.         {
  17.                 resPt = resultPoint;
  18.                 es = Acad::eOk;
  19.         }
  20.         return es;
  21. }
  22.  
в коде проверок нет, так что перед вызовом нужно убедиться на 100%, что точка лежит внутри или на границах треугольника, т.к. работа идет не с ограниченным рамками треугольником, а с бесконечной плоскостью.
vertex1, vertex2, vertex3 - это точки треугольника в 3D, resPt - это точка для которой нужно найти Z. то, что там лежит в Z на момент запуска - игнорируется.
ну и пример для тестирования функции
Код - C++ [Выбрать]
  1. AcDbObjectId eId;
  2. AcDbFace* pFace;
  3. AcDbPoint* pPoint;
  4. AcGePoint3d resPt;
  5. ads_name entcont;
  6.  
  7. if ( RTNORM != acedEntSel(_T("\nУкажите 3DFace: "),entcont,asDblArray(resPt)) ) return;
  8. acdbGetObjectId(eId,entcont);
  9. if(acdbOpenObject(pFace, eId, AcDb::kForRead)!= Acad::eOk) return;
  10. if (pFace == NULL) return;
  11.  
  12. if ( RTNORM != acedEntSel(_T("\nУкажите точку: "),entcont,asDblArray(resPt)) ) return;
  13. acdbGetObjectId(eId,entcont);
  14. if(acdbOpenObject(pPoint, eId, AcDb::kForRead)!= Acad::eOk) return;
  15. if (pPoint == NULL) return;
  16.  
  17. AcGePoint3d vertex1, vertex2, vertex3; // тут три точки треугольника в пространстве
  18. pFace->getVertexAt(0, vertex1);
  19. pFace->getVertexAt(1, vertex2);
  20. pFace->getVertexAt(2, vertex3);
  21. resPt = pPoint->position(); // отсюда нужна только плановая проекция (Z игнорируется)
  22. pPoint->close();
  23. pFace->close();
  24.  
  25. if (Acad::eOk == FindTrianglePt(vertex1, vertex2, vertex3, resPt))
  26.         addPoint(false,resPt,1,_T("0"),ACDB_MODEL_SPACE); // это нарисует примитив "точка" в автокаде. функция не ObjectARX, так что работать не будет )))
  27.