Поддержка команды ПОДЕЛИ (DIVIDE) в собственном примитиве
Вопрос:
Как обеспечить поддержку моим примитивом команды AutoCAD ПОДЕЛИ (DIVIDE)?
Ответ:
Чтобы обеспечить поддержку моим примитивом команды ПОДЕЛИ (DIVIDE) необходимо унаследовать его от класса AcDbCurve или одного из его производных классов. Минимальное количество методов, которое следует переопределить для работы команды ПОДЕЛИ (DIVIDE):
Acad::ErrorStatus getEndParam(double& endParam) const;
Acad::ErrorStatus getDistAtParam (double param, double& dist) const;
Acad::ErrorStatus getPointAtDist(double dist, AcGePoint3d& point) const;
Acad::ErrorStatus getPointAtParam(double param, AcGePoint3d& point) const;
В качестве примера того как переопределить эти методы рассмотрим пример PolySamp из ObjectARX SDK. Этот собственный примитив – просто замкнутый многоугольник.
Соответствующие переопределённые методы:
- virtual Acad::ErrorStatus
- getStartParam (double& startParam) const
- {
- assertReadEnabled();
- startParam = 0.0;
- return Acad::eOk;
- }
- virtual Acad::ErrorStatus getEndParam (double& endParam) const
- {
- assertReadEnabled();
- //замкнутая полилиния. Так что конечный параметр: 2* PI
- endParam = 6.28318530717958647692;
- return Acad::eOk;
- }
- Acad::ErrorStatus AsdkPoly::getDistAtParam(
- double param,
- double& dist) const
- {
- assertReadEnabled();
- rx_fixangle(param);
- double circumRadius =
- (startPoint() - center()).length();
- double alpha =
- 3.14159265358979323846 * 0.5 -
- 3.14159265358979323846 / mNumSides;
- double sideLength =
- 2.0 * circumRadius * cos(alpha);
- double includedAngle =
- 6.28318530717958647692 / mNumSides;
- int numIncludedAngles =
- int(param / includedAngle);
- double theta =
- param - numIncludedAngles * includedAngle;
- if (theta > 1.0e-10) {
- dist = sideLength * numIncludedAngles +
- circumRadius * sin(theta) /
- sin(3.14159265358979323846 - theta - alpha);
- } else {
- dist = sideLength * numIncludedAngles;
- }
- return Acad::eOk;
- }
- Acad::ErrorStatus
- AsdkPoly::getPointAtParam(
- double param,
- AcGePoint3d& point) const
- {
- assertReadEnabled();
- Acad::ErrorStatus es = Acad::eOk;
- // Узнаём сколько углов содержит "param".
- // Узнаём вершину и направление отрезка между этой вершиной
- // и следующей вершиной. Добавляем соответствующее расстояние
- // вдоль этого отрезка для получения новой точки.
- rx_fixangle(param);
- double circumRadius =
- (startPoint() - center()).length();
- double includedAngle=
- 6.28318530717958647692 / mNumSides;
- int numIncludedAngles =
- int(param / includedAngle);
- double theta =
- param - numIncludedAngles * includedAngle;
- double gamma =
- 3.14159265358979323846 * 0.5 +
- 3.14159265358979323846 / mNumSides - theta;
- double distToGo =
- circumRadius * sin(theta) / sin(gamma);
- AcGeVector3d lineDir =
- sideVector(numIncludedAngles);
- AcGePoint3dArray vertexArray;
- if ((es =
- getVertices3d(vertexArray)) != Acad::eOk) {
- return es;
- }
- if (theta > 1.0e-10) {
- point = vertexArray[numIncludedAngles] + (distToGo * lineDir);
- } else {
- point = vertexArray[numIncludedAngles];
- }
- return es;
- }
С помощью этих методов, когда команда ПОДЕЛИ (DIVIDE) выполняется и пользователь введёт количество сегментов для деления, например 10, AutoCAD разделит наш примитив вдоль сторон на заданное количество сегментов:
Источник: http://adndevblog.typepad.com/autocad/2013/02/supporting-the-divide-command-in-a-custom-entity.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=31
Отредактировано 05.06.2013 в 19:41:42