C#. Передать аргумент список 3Д точек
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > C#. Передать аргумент список 3Д точек

C#. Передать аргумент список 3Д точек

Ответ
Поиск в этой теме
Непрочитано 14.04.2025, 19:11 #1
C#. Передать аргумент список 3Д точек
sathalex
 
Регистрация: 02.07.2014
Сообщений: 59

Привет.
Никак не могу передать второй аргумент список 3Д точек.
Формат точек:
Код:
[Выделить все]
(list (list x1 y1 z1) (list x2 y2 z2)...)
Где я что упускаю?
Сам код:

Код:
[Выделить все]
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;

public class LispFunctions
{
    [LispFunction("CountPointsInsidePolyline")]
    public static int CountPointsInsidePolyline(ResultBuffer args)
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Editor ed = doc.Editor;
        Database db = doc.Database;

        if (args == null)
        {
            ed.WriteMessage("\nОшибка: аргументы не переданы.");
            return 0;
        }

        TypedValue[] argsArray = args.AsArray();
        if (argsArray.Length != 2)
        {
            ed.WriteMessage("\nОшибка: требуется 2 аргумента.");
            return 0;
        }

        if (!(argsArray[0].Value is ObjectId polylineId))
        {
            ed.WriteMessage("\nОшибка: первый аргумент должен быть полилинией.");
            return 0;
        }

        if (!(argsArray[1].Value is ResultBuffer pointsBuffer))
        {
            ed.WriteMessage("\nОшибка: второй аргумент должен быть списком точек.");
            return 0;
        }

        List<Point3d> points = new List<Point3d>();
        try
        {
            foreach (TypedValue tv in pointsBuffer)
            {
                if (tv.TypeCode == (int)LispDataType.ListBegin)
                {
                    ResultBuffer coordBuffer = tv.Value as ResultBuffer;
                    double[] coords = coordBuffer.AsArray()
                        .Take(3)
                        .Select(c => (double)Convert.ChangeType(c.Value, typeof(double)))
                        .ToArray();
                    points.Add(new Point3d(coords[0], coords[1], coords[2]));
                }
            }
        }
        catch (System.Exception)
        {
            ed.WriteMessage("\nОшибка: неверный формат точек.");
            return 0;
        }

        int count = 0;
        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            try
            {
                Entity entity = tr.GetObject(polylineId, OpenMode.ForRead) as Entity;
                if (entity == null || !IsClosedPolyline(entity))
                {
                    ed.WriteMessage("\nОшибка: объект не является замкнутой полилинией.");
                    return 0;
                }

                if (!(entity is Curve curve))
                {
                    ed.WriteMessage("\nОшибка: объект не является кривой.");
                    return 0;
                }

                List<Point2d> polygon = GetPolygonPoints(curve, tr);

                foreach (Point3d pt in points)
                {
                    Point2d checkPoint = new Point2d(pt.X, pt.Y);
                    if (IsPointInPolygon(polygon, checkPoint))
                        count++;
                }

                tr.Commit();
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"\nОшибка: {ex.Message}");
                return 0;
            }
        }

        return count;
    }

    private static bool IsClosedPolyline(Entity entity)
    {
        switch (entity)
        {
            case Polyline pl:
                return pl.Closed;
            case Polyline2d pl2d:
                return pl2d.Closed;
            default:
                return false;
        }
    }

    private static List<Point2d> GetPolygonPoints(Curve curve, Transaction tr)
    {
        List<Point2d> points = new List<Point2d>();

        if (curve is Polyline pl)
        {
            for (int i = 0; i < pl.NumberOfVertices; i++)
            {
                Point3d pt3d = pl.GetPoint3dAt(i);
                points.Add(new Point2d(pt3d.X, pt3d.Y));
            }
        }
        else if (curve is Polyline2d pl2d)
        {
            foreach (ObjectId vxId in pl2d)
            {
                Vertex2d vx = tr.GetObject(vxId, OpenMode.ForRead) as Vertex2d;
                if (vx != null)
                {
                    Point3d pt3d = vx.Position;
                    points.Add(new Point2d(pt3d.X, pt3d.Y));
                }
            }
        }

        return points;
    }

    private static bool IsPointInPolygon(List<Point2d> polygon, Point2d point)
    {
        bool inside = false;
        int count = polygon.Count;

        for (int i = 0, j = count - 1; i < count; j = i++)
        {
            if (((polygon[i].Y > point.Y) != (polygon[j].Y > point.Y)) &&
                (point.X < (polygon[j].X - polygon[i].X) * (point.Y - polygon[i].Y) /
                (polygon[j].Y - polygon[i].Y) + polygon[i].X))
            {
                inside = !inside;
            }
        }

        return inside;
    }
}
Просмотров: 296
 
Непрочитано 14.04.2025, 22:16
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,372


Студию запускать лениво. А что на самом деле приходит вторым (и далее) в argsArray?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 15.04.2025, 11:40
#3
trir


 
Регистрация: 18.12.2010
Сообщений: 5,100


(list (list x1 y1 z1) (list x2 y2 z2)...) => List<List<double>>
trir вне форума  
 
Непрочитано 15.04.2025, 15:40
#4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,372


Не уверен.
Скорее всего, будет нечто типа
Код:
[Выделить все]
if (resBuf == null)
{
    throw new ArgumentOutOfRangeException("Надо 2 аргумента");
}

TypedValue[] argsArray = resBuf.AsArray();
if (argsArray.Length <= 2)
{
    throw new ArgumentOutOfRangeException("\nОшибка: требуется 2 аргумента.");
}

ObjectId objId = (ObjectId)argsArray[0].Value;
List<Point3d> pointList = new List<Point3d>();
for (int i = 1; i < argsArray.Length; i++)
{
    TypedValue value = argsArray[i];
    if (value.TypeCode == (int)LispDataType.Point3d)
    {
        pointList.Add((Point3d) value.Value );
    }
}
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > C#. Передать аргумент список 3Д точек

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Solidworks 2014. Как создать выпадающий список? voverrr SolidWorks 1 18.02.2016 16:27
Autolisp. Как записать координаты нескольких точек в один структурированный список? vladimirr_b LISP 3 16.11.2015 13:55
Как передать функции (getkword) Список ключевых слов из списка? Kostinok Программирование 31 31.05.2012 13:08
построение линии через имеющийся список точек Composter Программирование 18 13.02.2012 10:43
Импорт точек из файла .job & .are G-RAV Программирование 34 20.08.2009 08:20