Flächenumring prüfen auf Überlappungen
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Morrison.
-
-
@jan99 Kannst Du dazu mal eine Skizze posten?Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
-
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()
-
-
Neu
@jan99 Sieh Dir mal an, was Wiki zuPolygon
schreibt:
de.wikipedia.org/wiki/Polygon#Regelm%C3%A4%C3%9Figes_PolygonFalls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
Neu
Nimm eine Physik Engine und prüf auf Kollision. Glaube das ist der einfachste weg. Da gibt es bestimmt irgend etwas fertiges um zu sehen ob sich etwas überlappt. Alternativ könntest du dein polygon in linien aufteilen also Punkt A zu B ist eine Line und Punkt B zu C und so weiter. Dann kannst du einfach prüfen ob sich diese linen miteinander überlappen.
Edit habe hier etwas gefunden: gist.github.com/unitycoder/10241239e080720376830f84511ccd3cDieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Andy“ ()
-
Neu
ChatGPT sagt:
Install-Package NetTopologySuite
Spoiler anzeigen VB.NET-Quellcode
- Imports NetTopologySuite.Geometries
- Imports NetTopologySuite.Operation.Overlay
- Module Module1
- Sub Main()
- ' Beispiel: Umring erstellen
- Dim factory As New GeometryFactory()
- Dim polygonCoords As Coordinate() = {
- New Coordinate(0, 0),
- New Coordinate(10, 0),
- New Coordinate(10, 10),
- New Coordinate(0, 10),
- New Coordinate(0, 0) ' Schließt den Umring
- }
- Dim polygon As Polygon = factory.CreatePolygon(polygonCoords)
- ' Beispiel: Punkte innerhalb der Fläche
- Dim pointCoords As Coordinate() = {
- New Coordinate(5, 5),
- New Coordinate(15, 15) ' Dieser Punkt liegt außerhalb
- }
- Dim points As MultiPoint = factory.CreateMultiPoint(pointCoords)
- ' Überprüfung, ob Punkte im Umring liegen
- For Each point In points.Geometries
- If polygon.Contains(point) Then
- Console.WriteLine($"Punkt {point} liegt im Umring.")
- Else
- Console.WriteLine($"Punkt {point} liegt außerhalb des Umrings.")
- End If
- Next
- ' Beispiel: Zwei Flächen prüfen, ob sie sich überschneiden
- Dim anotherPolygonCoords As Coordinate() = {
- New Coordinate(5, 5),
- New Coordinate(15, 5),
- New Coordinate(15, 15),
- New Coordinate(5, 15),
- New Coordinate(5, 5)
- }
- Dim anotherPolygon As Polygon = factory.CreatePolygon(anotherPolygonCoords)
- If polygon.Intersects(anotherPolygon) Then
- Console.WriteLine("Die Flächen überschneiden sich.")
- Else
- Console.WriteLine("Die Flächen überschneiden sich nicht.")
- End If
- End Sub
- End Module
Oder ohne externe Bibliothek:
Spoiler anzeigen
VB.NET-Quellcode
- Function IsPointInPolygon(polygon As List(Of PointF), point As PointF) As Boolean
- Dim intersects As Integer = 0
- Dim n As Integer = polygon.Count
- For i As Integer = 0 To n - 1
- Dim p1 As PointF = polygon(i)
- Dim p2 As PointF = polygon((i + 1) Mod n)
- ' Prüfe, ob die Linie [p1, p2] eine horizontale Linie nach rechts schneidet
- If (point.Y > Math.Min(p1.Y, p2.Y)) AndAlso (point.Y <= Math.Max(p1.Y, p2.Y)) AndAlso
- (point.X <= Math.Max(p1.X, p2.X)) Then
- Dim xinters As Double = (point.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X
- If p1.Y <> p2.Y AndAlso point.X <= xinters Then
- intersects += 1
- End If
- End If
- Next
- ' Ist die Anzahl der Schnitte ungerade, liegt der Punkt im Polygon
- Return (intersects Mod 2) <> 0
- End Function
- Function DoLinesIntersect(p1 As PointF, p2 As PointF, q1 As PointF, q2 As PointF) As Boolean
- ' Berechnung der Orientierung
- Dim o1 As Integer = Orientation(p1, p2, q1)
- Dim o2 As Integer = Orientation(p1, p2, q2)
- Dim o3 As Integer = Orientation(q1, q2, p1)
- Dim o4 As Integer = Orientation(q1, q2, p2)
- ' Allgemeine Überschneidung
- If (o1 <> o2) AndAlso (o3 <> o4) Then Return True
- ' Spezialfälle: Endpunkte liegen auf einer Linie
- If (o1 = 0 AndAlso IsOnSegment(p1, q1, p2)) Then Return True
- If (o2 = 0 AndAlso IsOnSegment(p1, q2, p2)) Then Return True
- If (o3 = 0 AndAlso IsOnSegment(q1, p1, q2)) Then Return True
- If (o4 = 0 AndAlso IsOnSegment(q1, p2, q2)) Then Return True
- Return False
- End Function
- Function Orientation(p As PointF, q As PointF, r As PointF) As Integer
- ' Berechnet die Orientierung von drei Punkten
- Dim val As Double = (q.Y - p.Y) * (r.X - q.X) - (q.X - p.X) * (r.Y - q.Y)
- If val = 0 Then Return 0 ' Kollinear
- Return If(val > 0, 1, 2) ' Uhrzeigersinn oder gegen Uhrzeigersinn
- End Function
- Function IsOnSegment(p As PointF, q As PointF, r As PointF) As Boolean
- Return (q.X <= Math.Max(p.X, r.X) AndAlso q.X >= Math.Min(p.X, r.X) AndAlso
- q.Y <= Math.Max(p.Y, r.Y) AndAlso q.Y >= Math.Min(p.Y, r.Y))
- End Function
- Function DoPolygonsIntersect(polygon1 As List(Of PointF), polygon2 As List(Of PointF)) As Boolean
- For i As Integer = 0 To polygon1.Count - 1
- Dim p1 As PointF = polygon1(i)
- Dim p2 As PointF = polygon1((i + 1) Mod polygon1.Count)
- For j As Integer = 0 To polygon2.Count - 1
- Dim q1 As PointF = polygon2(j)
- Dim q2 As PointF = polygon2((j + 1) Mod polygon2.Count)
- If DoLinesIntersect(p1, p2, q1, q2) Then
- Return True
- End If
- Next
- Next
- Return False
- End Function
- Sub Main()
- Dim polygon1 As New List(Of PointF) From {
- New PointF(0, 0),
- New PointF(10, 0),
- New PointF(10, 10),
- New PointF(0, 10)
- }
- Dim polygon2 As New List(Of PointF) From {
- New PointF(5, 5),
- New PointF(15, 5),
- New PointF(15, 15),
- New PointF(5, 15)
- }
- ' Prüfe Überschneidung
- If DoPolygonsIntersect(polygon1, polygon2) Then
- Console.WriteLine("Die Polygone überschneiden sich.")
- Else
- Console.WriteLine("Die Polygone überschneiden sich nicht.")
- End If
- ' Prüfe Punkt in Polygon
- Dim testPoint As New PointF(5, 5)
- If IsPointInPolygon(polygon1, testPoint) Then
- Console.WriteLine("Der Punkt liegt im Polygon.")
- Else
- Console.WriteLine("Der Punkt liegt außerhalb des Polygons.")
- End If
- End Sub
- Function HasSelfIntersections(polygon As List(Of PointF)) As Boolean
- Dim n As Integer = polygon.Count
- For i As Integer = 0 To n - 1
- Dim p1 As PointF = polygon(i)
- Dim p2 As PointF = polygon((i + 1) Mod n)
- For j As Integer = 0 To n - 1
- ' Überspringe benachbarte Kanten und dieselbe Kante
- If j = i OrElse j = (i + 1) Mod n OrElse (j + 1) Mod n = i Then
- Continue For
- End If
- Dim q1 As PointF = polygon(j)
- Dim q2 As PointF = polygon((j + 1) Mod n)
- If DoLinesIntersect(p1, p2, q1, q2) Then
- Return True ' Überschneidung gefunden
- End If
- Next
- Next
- Return False ' Keine Überschneidungen
- End Function
- Sub Main()
- Dim polygonOk As New List(Of PointF) From {
- New PointF(0, 0),
- New PointF(10, 0),
- New PointF(10, 10),
- New PointF(0, 10)
- }
- Dim polygonWrong As New List(Of PointF) From {
- New PointF(0, 0),
- New PointF(10, 0),
- New PointF(5, 5),
- New PointF(10, 10),
- New PointF(0, 10)
- }
- If HasSelfIntersections(polygonOk) Then
- Console.WriteLine("Polygon OK: Hat Selbstüberschneidungen")
- Else
- Console.WriteLine("Polygon OK: Keine Selbstüberschneidungen")
- End If
- If HasSelfIntersections(polygonWrong) Then
- Console.WriteLine("Polygon Falsch: Hat Selbstüberschneidungen")
- Else
- Console.WriteLine("Polygon Falsch: Keine Selbstüberschneidungen")
- End If
- End Sub
Die hochgeladene Datei zeigt zwei Beispiele:
Links (OK): Ein Polygon, dessen Linien sich nicht überschneiden.
Rechts (Falsch): Ein Polygon, dessen Linien sich gegenseitig überschneiden.
Das Problem hier ist, Selbstüberschneidungen innerhalb eines Polygons zu erkennen. Das bedeutet, dass überprüft werden muss, ob eine Linie des Polygons eine andere Linie desselben Polygons schneidet.
Lösung ohne zusätzliche Bibliotheken
Du kannst die Funktion DoLinesIntersect aus meinem vorherigen Vorschlag verwenden, um die Kanten des Polygons miteinander zu vergleichen.
Algorithmus:Iteriere über jede Kante des Polygons.
Vergleiche jede Kante mit allen anderen Kanten des Polygons.
Überspringe benachbarte Kanten, da diese sich teilen dürfen (gemeinsamer Punkt).
Überprüfe mit DoLinesIntersect, ob sich zwei Kanten schneiden.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Morrison“ ()
-
Benutzer online 1
1 Besucher
-
Ähnliche Themen
-
Camshot - - Sonstige Problemstellungen
-
6 Benutzer haben hier geschrieben
- VB1963 (2)
- RodFromGermany (2)
- jan99 (2)
- Morrison (1)
- Haudruferzappeltnoch (1)
- Andy (1)