Сообщество программистов Autodesk в СНГ

ADN Club => ObjectARX => Тема начата: knightrocker от 17-05-2018, 10:59:26

Название: Как разместить круг касающийся двух линий
Отправлено: knightrocker от 17-05-2018, 10:59:26
Добрый день.
Разрабатываю модуль *.arx в Visual Studio на C++ который уже после подгружаю в Автокад и пытаюсь выполнить внутри него следующее:
 
Вопрос в следующем, имею три точки (координаты каждой из них), причём
Точка_1 это начало первой линии и Точка_2 её конец. Точка_2 это начало второй линии и Точка_3 её конец.
Две линии успешно рисуются средствами AcDbLine из ObjectARX.
Задача: Необходимо в образованный этими линиями угол вписать окружность с заданным Радиусом.
Радиус, как и координаты точек вводятся пользователем.
Вопрос: Подскажите хотябы последоватльность действий или методов, которые стоит применить для того чтобы успешнос вписать
объект круг между двумя другими объектами (линиями), или как тут стоит использовать AcGeVector3d ?
Название: Re: Как разместить круг касающийся двух линий
Отправлено: Александр Ривилис от 17-05-2018, 11:02:44
Вопрос: Подскажите хотябы последоватльность действий или методов, которые стоит применить для того чтобы успешнос вписать
объект круг между двумя другими объектами (линиями), или как тут стоит использовать AcGeVector3d ?
Тут чистая аналитическая геометрия. Здесь есть всё, что необходимо для получения центра вписанной окружности по тем данным, которые есть:
https://ru.wikipedia.org/wiki/%D0%92%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BE%D0%BA%D1%80%D1%83%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C
Название: Re: Как разместить круг касающийся двух линий
Отправлено: Александр Ривилис от 17-05-2018, 13:22:27
Это ответ на основной вопрос:

Код - C++ [Выбрать]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.h
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include "resource.h"
  6. #define _USE_MATH_DEFINES
  7. #include <math.h>
  8.  
  9. //-----------------------------------------------------------------------------
  10. #define szRDS _RXST("")
  11.  
  12. Acad::ErrorStatus postToDwg (AcDbEntity *pEnt, AcDbDatabase *pDb, ACHAR *requiredSpace);
  13.  
  14. //-----------------------------------------------------------------------------
  15. //----- ObjectARX EntryPoint
  16. class CCircleInAngleApp : public AcRxArxApp {
  17.  
  18. public:
  19.         CCircleInAngleApp () : AcRxArxApp () {}
  20.  
  21.         virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
  22.                 AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
  23.                 return (retCode) ;
  24.         }
  25.  
  26.         virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
  27.                 AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
  28.                 return (retCode) ;
  29.         }
  30.  
  31.         virtual void RegisterServerComponents () {      }
  32.  
  33. public:
  34.  
  35.   // - CircleInAngle.CreateCircle command (do not rename)
  36.   static void CircleInAngleCreateCircle(void)
  37.   {
  38.     AcGePoint3d p1, p2, p3;
  39.     if (acedGetPoint(NULL,           L"\nP1: ", asDblArray(p1)) != RTNORM) return;
  40.     if (acedGetPoint(asDblArray(p1), L"\nP2: ", asDblArray(p2)) != RTNORM) return;
  41.     if (acedGetPoint(asDblArray(p2), L"\nP3: ", asDblArray(p3)) != RTNORM) return;
  42.     double r = 0;
  43.     acedInitGet(7, NULL);
  44.     if (acedGetDist(asDblArray(p2), L"\nR: ", &r) != RTNORM) return;
  45.     // Первый отрезок
  46.     AcDbLine *pLine1 = new AcDbLine(p1, p2);
  47.     pLine1->setDatabaseDefaults(acdbCurDwg());
  48.     postToDwg(pLine1, NULL, NULL);
  49.     pLine1->close();
  50.     // Второй отрезок
  51.     AcDbLine *pLine2 = new AcDbLine(p2, p3);
  52.     pLine2->setDatabaseDefaults(acdbCurDwg());
  53.     postToDwg(pLine2, NULL, NULL);
  54.     pLine2->close();
  55.    
  56.     AcGeVector3d v1 = p1 - p2;
  57.     AcGeVector3d v2 = p3 - p2;
  58.     double ang = v1.angleTo(v2);
  59.     // Расстояние до центра окружности из вершины угла
  60.     double l = r / sin (ang * 0.5);
  61.     // Строим биссектрису угла
  62.     AcGePoint3d p11 = p2 + AcGeVector3d(p1 - p2).normalize() * l;
  63.     AcGePoint3d p33 = p2 + AcGeVector3d(p3 - p2).normalize() * l;
  64.     AcGePoint3d pMid = p11 + AcGeVector3d(p33 - p11) * 0.5;
  65.     // Вектор биссиктрисы
  66.     AcGeVector3d vb = AcGeVector3d(pMid - p2).normalize();
  67.     // Точка центра вписанной окружности
  68.     AcGePoint3d pc = p2 + vb * l;
  69.     AcDbCircle *pCircle = new AcDbCircle(pc, AcGeVector3d::kZAxis, r);
  70.     pCircle->setDatabaseDefaults(acdbCurDwg());
  71.     postToDwg(pCircle, NULL, NULL);
  72.     pCircle->close();
  73.   }
  74. } ;
  75.  
  76. Acad::ErrorStatus postToDwg (AcDbEntity *pEnt, AcDbDatabase *pDb, ACHAR *requiredSpace)
  77. {
  78.   // if the default database is to be used
  79.   if (pDb == NULL) {
  80.     pDb = acdbHostApplicationServices ()->workingDatabase ();
  81.   }
  82.  
  83.   AcDbBlockTable *blockTable = NULL;
  84.   // get a pointer to the block table
  85.   Acad::ErrorStatus es = pDb->getBlockTable (blockTable, AcDb::kForRead);
  86.   // if it failed then abort
  87.   if (es != Acad::eOk)
  88.     return (es);
  89.  
  90.   AcDbBlockTableRecord *blockTableRecord = NULL;
  91.   // now get a pointer to the model space entity records
  92.   if (requiredSpace)  {
  93.     es = blockTable->getAt (requiredSpace, blockTableRecord, AcDb::kForWrite);
  94.   } else {
  95.     es = acdbOpenObject(blockTableRecord, pDb->currentSpaceId(), AcDb::kForWrite);
  96.   }
  97.   // can close the block table itself as we don't need it anymore
  98.   blockTable->close ();
  99.   // if it failed then abort
  100.   if (es != Acad::eOk)
  101.     return (es);
  102.   // otherwise put the entity into the model space
  103.   es = blockTableRecord->appendAcDbEntity (pEnt);
  104.   // now close it up
  105.   blockTableRecord->close();
  106.   // close entity
  107.   return (es);
  108. }
  109.  
  110.  
  111.  
  112. //-----------------------------------------------------------------------------
  113. IMPLEMENT_ARX_ENTRYPOINT(CCircleInAngleApp)
  114.  
  115. ACED_ARXCOMMAND_ENTRY_AUTO(CCircleInAngleApp, CircleInAngle, CreateCircle, CC, ACRX_CMD_TRANSPARENT, NULL)
  116.  
  117.  
Название: Re: Как разместить круг касающийся двух линий
Отправлено: knightrocker от 22-05-2018, 13:16:30
Александр, огромное спасибо за столь развёрнутый ответ!
Название: Re: Как разместить круг касающийся двух линий
Отправлено: Александр Ривилис от 22-05-2018, 13:44:21
Александр, огромное спасибо за столь развёрнутый ответ!
Есть такая кнопка, которая называется Решение, которую нужно не забывать нажимать если был предоставлен правильный ответ.