Получить оффсет полилинии/линии

Автор Тема: Получить оффсет полилинии/линии  (Прочитано 3484 раз)

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

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

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Здравствуйте.
Возник вопрос: есть полилиния, рядом с которой я хочу создать еще одну при помощи оффсета. У меня есть подозрение, что направление в котором я рисовал влияет на появление второй полилинии относительно исходной.
Делаю так :
Код - C# [Выбрать]
  1. DBObjectCollection acDbObjColl = acPoly.GetOffsetCurves();
Иногда полилиния сверху, иногда снизу.
Есть ли способ четко знать в каком месте она появится?
Заранее спасибо

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить оффсет полилинии/линии
« Ответ #1 : 23-08-2017, 16:18:02 »
У меня есть подозрение, что направление в котором я рисовал влияет на появление второй полилинии относительно исходной.
Правильное подозрение. Только почему сверху/снизу? Что ты имеешь в виду?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Re: Получить оффсет полилинии/линии
« Ответ #2 : 23-08-2017, 16:26:25 »
Я рисую горизонтальную полилинию, соответственно полилиния с оффсетом получается либо сверху либо снизу.
В общем случае по разные стороны от оригинала.
Можно ли сделать так, чтобы независимо от направление рисования, оффсет был в одну сторону?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить оффсет полилинии/линии
« Ответ #3 : 23-08-2017, 16:54:24 »
Можно ли сделать так, чтобы независимо от направление рисования, оффсет был в одну сторону?
Да. Меняй знак у оффсета. Читаем документацию:

Цитировать
To offset an object, use the GetOffsetCurves method provided for that object. The function requires a positive or negative numeric value for the distance to offset the object. If the distance is negative, it is interpreted by AutoCAD as being an offset to make a “smaller” curve (that is, for an arc it would offset to a radius that is the given distance less than the starting curve's radius). If “smaller” has no meaning, then AutoCAD would offset in the direction of smaller X,Y,Z WCS coordinates.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Re: Получить оффсет полилинии/линии
« Ответ #4 : 23-08-2017, 17:03:16 »
Спасибо, сейчас посмотрю!

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить оффсет полилинии/линии
« Ответ #5 : 23-08-2017, 17:04:31 »
Кстати, когда-то я написал такую программку:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. [assembly: CommandClass(typeof(Rivilis.CurveUtils))]
  9.  
  10. namespace Rivilis
  11. {
  12.   public class CurveUtils
  13.   {
  14.     [CommandMethod("OffsetCurve", CommandFlags.Modal)]
  15.     public static void OffsetCurve()
  16.     {
  17.       Document doc = Application.DocumentManager.MdiActiveDocument;
  18.       Editor ed = doc.Editor;
  19.       PromptDoubleResult resValueOff = ed.GetDistance("\nВеличина смещения: ");
  20.       if (resValueOff.Status != PromptStatus.OK) return;
  21.       PromptPointResult  resPointOff = ed.GetPoint("\nСторона смещения: ");
  22.       if (resPointOff.Status != PromptStatus.OK) return;
  23.       PromptEntityOptions prCurv = new PromptEntityOptions("\nВыберите кривую: ");
  24.       prCurv.SetRejectMessage("это не кривая");
  25.       prCurv.AddAllowedClass(typeof(Curve),false);
  26.       PromptEntityResult resCurv = ed.GetEntity(prCurv);
  27.       if (resCurv.Status != PromptStatus.OK) return;
  28.      
  29.       using  (Transaction tr = doc.TransactionManager.StartTransaction()) {
  30.         Curve curve = tr.GetObject(resCurv.ObjectId, OpenMode.ForRead) as Curve;
  31.         if (curve != null) {
  32.           BlockTableRecord btr = tr.GetObject(curve.BlockId, OpenMode.ForWrite) as BlockTableRecord;
  33.           if (btr != null) {
  34.             Point3d pDir = (Point3d)(Application.GetSystemVariable("VIEWDIR"));
  35.             if (pDir != null) {
  36.               Point3d pWCS = resPointOff.Value.TransformBy(ed.CurrentUserCoordinateSystem);
  37.               double offset = IsRightDirection(curve, pWCS, pDir.GetAsVector()) ?
  38.                      resValueOff.Value : -resValueOff.Value;
  39.               DBObjectCollection curvCols = curve.GetOffsetCurves(offset);
  40.               foreach (DBObject obj in curvCols) {
  41.                 Curve subCurv = obj as Curve;
  42.                 if (subCurv != null) {
  43.                   btr.AppendEntity(subCurv);
  44.                   tr.AddNewlyCreatedDBObject(subCurv, true);
  45.                 }
  46.               }
  47.             }
  48.           }
  49.         }
  50.         tr.Commit();
  51.       }
  52.     }
  53.     // Detect side of point
  54.     public static bool IsRightDirection(Curve pCurv, Point3d p, Vector3d vDir)
  55.     {
  56.       Vector3d vNormal = Vector3d.ZAxis;
  57.       if (pCurv.IsPlanar) {
  58.         Plane plane = pCurv.GetPlane();
  59.         vNormal = plane.Normal;
  60.         p = p.Project(plane, vDir);
  61.       }
  62.       Point3d pNear = pCurv.GetClosestPointTo(p, true);
  63.       Vector3d vSide = p - pNear;
  64.       Vector3d vDeriv = pCurv.GetFirstDerivative(pNear);
  65.       if (vNormal.CrossProduct(vDeriv).DotProduct(vSide) < 0.0)
  66.         return true;
  67.       else
  68.         return false;
  69.     }
  70.   }
  71. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение