Как разместить круг касающийся двух линий

Автор Тема: Как разместить круг касающийся двух линий  (Прочитано 6960 раз)

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

Оффлайн knightrockerАвтор темы

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Добрый день.
Разрабатываю модуль *.arx в Visual Studio на C++ который уже после подгружаю в Автокад и пытаюсь выполнить внутри него следующее:
 
Вопрос в следующем, имею три точки (координаты каждой из них), причём
Точка_1 это начало первой линии и Точка_2 её конец. Точка_2 это начало второй линии и Точка_3 её конец.
Две линии успешно рисуются средствами AcDbLine из ObjectARX.
Задача: Необходимо в образованный этими линиями угол вписать окружность с заданным Радиусом.
Радиус, как и координаты точек вводятся пользователем.
Вопрос: Подскажите хотябы последоватльность действий или методов, которые стоит применить для того чтобы успешнос вписать
объект круг между двумя другими объектами (линиями), или как тут стоит использовать AcGeVector3d ?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вопрос: Подскажите хотябы последоватльность действий или методов, которые стоит применить для того чтобы успешнос вписать
объект круг между двумя другими объектами (линиями), или как тут стоит использовать 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
« Последнее редактирование: 17-05-2018, 11:33:13 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Александр Ривилис 22-05-2018, 15:38:42

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Это ответ на основной вопрос:

Код - 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.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн knightrockerАвтор темы

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Александр, огромное спасибо за столь развёрнутый ответ!

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр, огромное спасибо за столь развёрнутый ответ!
Есть такая кнопка, которая называется Решение, которую нужно не забывать нажимать если был предоставлен правильный ответ.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение