Archivo de la etiqueta: continuidad

Detectando líneas sin continuidad

Aquí el vídeo relacionado con esta entrada

En ocasiones nos interesa realizar análisis de continuidad geométrica.

Quizás queramos detectar como error líneas que no tienen continuidad, es decir, que en las coordenadas de alguno de sus extremos no nace otra línea, o quizás justo lo contrario, una línea que continúa con otra con un código que las hace incompatibles, como curva de nivel fina con curva de nivel maestra, o dos curvas de nivel finas pero con distinta coordenada Z, …

Si queremos hacer un control de bordes, quizás nos interese detectar como errores líneas que en la práctica no tienen la obligación de continuar con otra línea, pero que finalizan en un marco de hoja y no continúan en otro archivo.

Todos estos análisis los podemos realizar mediante el tipo Digi21.DigiNG.Topology.NodeDetector que implementa una serie de métodos de extensión que se ejecutan sobre una secuencia de líneas y que nos devolverá una secuencia de IGrouping<Point2D, VertexPointer>, es decir, una secuencia de entidades agrupadas por el punto en el que coinciden esas entidades.

El tipo Digi21.DigiNG.Entities.VertexPointer es muy parecido al tipo Digi21.DigiNG.Entities.SegmentPointer, dispone de dos propiedades: una para indicar la línea que llega al nodo y otra para indicar el vértice de esa línea que llega al nodo.

A continuación la definición de este tipo:

namespace Digi21.DigiNG.Entities
{
    public struct VertexPointer
    {
        public VertexPointer(ReadOnlyLine line, int vertex);

        public ReadOnlyLine Line { get; }
        public int Vertex { get; }
    }
}

Al igual que en el caso del detector de intersecciones, dispondemos de varias sobrecargas del método de extensión que nos permitirán o detectar todos los nodos, o especificar si permitimos analizar una determinada entidad o si nos interesa un nodo en unas determinadas coordenadas o una combinación de estas opciones.

Veamos un ejemplo muy sencillo: vamos a crear una orden que añade tantas tareas en la ventana de tareas como entidades que no tienen continuidad.
Lo que vamos a hacer es detectar todos los nodos y crear una consulta Linq que se quede únicamente con la secuencia de nodos que estén formados únicamente por una entidad.

Si tenemos dos líneas, A y B, ambas formadas por dos puntos, y con las siguientes coordenadas: A: (100, 100) – (200, 200) y B: (200, 200) – (300, 100) tendremos tres nodos, uno en las coordenadas (100, 100) al que llega únicamente una entidad, la entidad A, un segundo nodo (200, 200) al que llegan dos entidades, la A y la B y por último el tercer nodo (300, 100) al que llega únicamente la entidad B.

Está claro que los nodos A y B son nodos en los que no hay continuidad pues únicamente llega a ellos una línea.

Aquí el código de la orden:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Digi21.DigiNG.Plugin.Command;
using Digi21.DigiNG.Topology;
using Digi21.DigiNG;
using Digi21.DigiNG.Entities;
using Digi21.Digi3D;
using Digi21.Math;

namespace Acme
{
    [Command(Name="detectar_líneas_sin_continuidad")]
    public class DetectarLíneasSinContinuidad : Command
    {
        public DetectarLíneasSinContinuidad()
        {
            this.Initialize += new EventHandler(DetectarLíneasSinContinuidad_Initialize);
        }

        void DetectarLíneasSinContinuidad_Initialize(object sender, EventArgs e)
        {
            try
            {
                var todosLosNodos = DigiNG.DrawingFile.OfType<ReadOnlyLine>().DetectNodes();

                var nodosConUnaÚnicaLínea = from nodo in todosLosNodos
                                            where nodo.Count() == 1
                                            select nodo;

                foreach (var nodo in nodosConUnaÚnicaLínea)
                    Digi3D.Tasks.Add(new TaskEntityGotoPoint(
                        (Point3D)nodo.Key,
                        nodo.ElementAt(0).Line,
                        2,
                        "Extremo de línea sin continuidad",
                        TaskSeverity.Error,
                        DigiNG.DrawingFile.Path,
                        "detectar_líneas_sin_continuidad"));
                DigiNG.RenderScene();
            }
            finally
            {
                Dispose();
            }
        }
    }
}

Muy sencillo, ¿no?. Con esto hemos simulado la opción de Bintram que marca como errores entidades sin continuidad.

Vamos a añadir una tabla de códigos a nuestra orden. Ahora la orden va tener en cuenta únicamente las líneas que tengan alguno de los códigos pasados por parámetros:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Digi21.DigiNG.Plugin.Command;
using Digi21.DigiNG.Topology;
using Digi21.DigiNG;
using Digi21.DigiNG.Entities;
using Digi21.Digi3D;
using Digi21.Math;
using UtilidadesDigi;

namespace Acme
{
    [Command(Name="detectar_líneas_sin_continuidad")]
    public class DetectarLíneasSinContinuidad : Command
    {
        public DetectarLíneasSinContinuidad()
        {
            this.Initialize += new EventHandler(DetectarLíneasSinContinuidad_Initialize);
        }

        void DetectarLíneasSinContinuidad_Initialize(object sender, EventArgs e)
        {
            try
            {
                if (this.Args.Length == 0)
                {
                    Digi3D.Music(MusicType.Error);
                    Digi3D.ShowBallon(
                        "detectar_líneas_sin_continuidad",
                        "No has indicado los códigos de las entidades a analizar",
                        2,
                        BallonIcon.Error);
                    return;
                }

//                var todosLosNodos = DigiNG.DrawingFile.QueTenganAlgúnCódigo(this.Args).SoloLíneas().DetectNodes();
                var todosLosNodos = DigiNG.DrawingFile.
                    SoloLíneasSinEliminar().DetectNodes(
                    entidad => entidad.TieneAlgúnCódigo(this.Args));


                var nodosConUnaÚnicaLínea = from nodo in todosLosNodos
                                            where nodo.Count() == 1
                                            select nodo;

                foreach (var nodo in nodosConUnaÚnicaLínea)
                    Digi3D.Tasks.Add(new TaskEntityGotoPoint(
                        (Point3D)nodo.Key,
                        nodo.ElementAt(0).Line,
                        2,
                        "Extremo de línea sin continuidad",
                        TaskSeverity.Error,
                        DigiNG.DrawingFile.Path,
                        "detectar_líneas_sin_continuidad"));
                DigiNG.RenderScene();
            }
            finally
            {
                Dispose();
            }
        }
    }
}