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

ADN Club => AutoCAD .NET API => Тема начата: Denis от 23-08-2017, 16:09:55

Название: Получить оффсет полилинии/линии
Отправлено: Denis от 23-08-2017, 16:09:55
Здравствуйте.
Возник вопрос: есть полилиния, рядом с которой я хочу создать еще одну при помощи оффсета. У меня есть подозрение, что направление в котором я рисовал влияет на появление второй полилинии относительно исходной.
Делаю так :
Код - C# [Выбрать]
  1. DBObjectCollection acDbObjColl = acPoly.GetOffsetCurves();
Иногда полилиния сверху, иногда снизу.
Есть ли способ четко знать в каком месте она появится?
Заранее спасибо
Название: Re: Получить оффсет полилинии/линии
Отправлено: Александр Ривилис от 23-08-2017, 16:18:02
У меня есть подозрение, что направление в котором я рисовал влияет на появление второй полилинии относительно исходной.
Правильное подозрение. Только почему сверху/снизу? Что ты имеешь в виду?
Название: Re: Получить оффсет полилинии/линии
Отправлено: Denis от 23-08-2017, 16:26:25
Я рисую горизонтальную полилинию, соответственно полилиния с оффсетом получается либо сверху либо снизу.
В общем случае по разные стороны от оригинала.
Можно ли сделать так, чтобы независимо от направление рисования, оффсет был в одну сторону?
Название: Re: Получить оффсет полилинии/линии
Отправлено: Александр Ривилис от 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.
Название: Re: Получить оффсет полилинии/линии
Отправлено: Denis от 23-08-2017, 17:03:16
Спасибо, сейчас посмотрю!
Название: Re: Получить оффсет полилинии/линии
Отправлено: Александр Ривилис от 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. }