IntersectionDetector
Espacio de nombres: Digi21.DigiNG.Topology
Ensamblado: Digi21.DigiNG.Topology
Detecta las intersecciones en el plano XY entre las líneas de una secuencia, o entre una línea y las de una secuencia.
public static class IntersectionDetector
Resultado
Todos los métodos devuelven un IEnumerable<IGrouping<Point2D, SegmentPointer>>. Cada elemento es una intersección:
Keyes la coordenada XY de la intersección.- Los elementos del grupo son SegmentPointer, uno por cada línea y segmento que pasan por esa coordenada.
Linees la misma instancia de la secuencia de entrada. Si la intersección está en el interior del segmento,FirstVertexes el índice del primer vértice del segmento ySecondVertexel del segundo. Si la intersección coincide con un vértice de la línea,FirstVertexySecondVertexvalen el índice de ese vértice.
Dos intersecciones con la misma coordenada, con la tolerancia de Precision.Epsilon, forman un solo grupo. Los grupos se devuelven ordenados por X y, a igual X, por Y. Las intersecciones se calculan al llamar al método, y el resultado se puede recorrer varias veces.
Una intersección es un punto en el que se cortan dos segmentos o, si dos segmentos se superponen, cada extremo del tramo común. Las líneas eliminadas (Deleted) y las que tienen menos de 2 vértices no se analizan.
Para filtrar el resultado por línea y segmento, usa UtilidadesSecuenciaIntersecciones.SoloDeSegmento, del paquete Digi21.Utilities.
Métodos estáticos
DetectIntersections (secuencia de líneas)
public static IEnumerable<IGrouping<Point2D, SegmentPointer>> DetectIntersections(
this IEnumerable<ReadOnlyLine> entities,
Func<ReadOnlyLine, bool> analyzeIntersectionsOfThisLine,
Func<ReadOnlyLine, ReadOnlyLine, bool> analyzeIntersectionsBetweenThisLines,
Func<Point2D, bool> insertIntersectionInThisCoordinate)
Detecta las intersecciones entre todas las líneas de entities y las autointersecciones de cada línea (los cruces de una línea consigo misma). Hay una sobrecarga por cada combinación de los tres delegados: DetectIntersections(entities), DetectIntersections(entities, analyzeIntersectionsOfThisLine), DetectIntersections(entities, analyzeIntersectionsBetweenThisLines), DetectIntersections(entities, insertIntersectionInThisCoordinate) y las de dos delegados, siempre en el orden de la firma completa. Un delegado que falta no filtra.
| Parámetro | Descripción |
|---|---|
entities |
Líneas que se analizan. Se recorre una sola vez. |
analyzeIntersectionsOfThisLine |
Se llama con cada línea de entities. Si devuelve false, la línea no se analiza. |
analyzeIntersectionsBetweenThisLines |
Se llama con cada pareja de líneas cuyas cajas (coordenadas mínimas y máximas en XY) se tocan. Si devuelve false, no se buscan intersecciones entre las dos. Para las autointersecciones se llama con la misma línea en los dos parámetros. |
insertIntersectionInThisCoordinate |
Se llama con la coordenada de cada intersección, una vez por cada línea que pasa por ella. Si devuelve false, ese SegmentPointer no se añade al resultado. |
Las autointersecciones solo se buscan en las líneas de más de 2 vértices. En una autointersección, el grupo contiene dos SegmentPointer de la misma línea, uno por cada segmento que se cruza.
DetectIntersections (una línea)
public static IEnumerable<IGrouping<Point2D, SegmentPointer>> DetectIntersections(
this ReadOnlyLine line,
IEnumerable<ReadOnlyLine> entities,
Func<ReadOnlyLine, bool> analyzeIntersectionsWithThisLine,
Func<Point2D, bool> insertIntersectionInThisCoordinate)
Detecta las intersecciones de line con las líneas de entities. Hay sobrecargas sin delegados, solo con analyzeIntersectionsWithThisLine y solo con insertIntersectionInThisCoordinate.
| Parámetro | Descripción |
|---|---|
line |
Línea que se analiza. No se buscan sus autointersecciones. |
entities |
Líneas con las que se cruza line. Se omite line si está en la secuencia (la misma instancia) y cada línea cuya caja no toca la de line. |
analyzeIntersectionsWithThisLine |
Se llama con cada línea de entities cuya caja toca la de line. Si devuelve false, la línea no se analiza. |
insertIntersectionInThisCoordinate |
Se llama con la coordenada de cada intersección. Si devuelve false, la intersección no se añade al resultado. |
Por cada intersección se añaden dos SegmentPointer: uno de line y otro de la línea de entities que la corta. Si varias líneas cortan a line en la misma coordenada, el grupo de esa coordenada contiene los SegmentPointer de todas.
Ejemplo
Este programa busca los cruces entre las líneas no eliminadas de un archivo .bin, sin las autointersecciones, y muestra las líneas que se cruzan en cada punto:
using Digi21.DigiNG.Entities;
using Digi21.DigiNG.IO.Bin;
using Digi21.DigiNG.Topology;
using Digi21.Math;
if (args.Length != 1)
{
Console.WriteLine("Uso: Cruces <archivo.bin>");
return 1;
}
using var archivo = new Bin(args[0], 2, new Point3D(0, 0, 0), true);
var líneas = archivo.OfType<ReadOnlyLine>().ToList();
var cruces = líneas.DetectIntersections(
analyzeIntersectionsBetweenThisLines: (a, b) => !ReferenceEquals(a, b));
foreach (var cruce in cruces)
{
var segmentos = cruce.Select(s => $"línea {líneas.IndexOf(s.Line)}, vértices {s.FirstVertex}-{s.SecondVertex}");
Console.WriteLine($"({cruce.Key.X:F2}, {cruce.Key.Y:F2}): {string.Join("; ", segmentos)}");
}
return 0;