Frage von 55555555555555, 55

VB.Net Schnittmenge von Kreisen?

Hallo

Wie kann ich mit Visual Basic die Schnittmenge zweier Kreise oder Polygone errechnen? Das mit den Kreisen bräuchte ich häufiger.

Zum Beispiel:

Kreis 1: {X=48, Y=77} Radius 23

Kreis 2: {X=52, Y=72} Radius 66

Welche Koordinaten haben nun eine Schnittmenge dieser Kreise? Wie berechne ich das? Es braucht kein fertiger VB Code sein, nur ein kleiner Ansatz würde mir schon super helfen!

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von Schachpapa, 38

Willst du alle Punkte haben, die in beiden Kreisen liegen, oder reicht es für einen Punkt zu bestimmen, ob er innerhalb beider Kreise liegt? Letzteres ist einfacher.

(x-48)^2+(y-77)^2 < 23^2 für Kreis 1

und analog für Kreis 2. Wenn beides wahr ist, liegt der Punkt innerhalb beider Kreise. Da macht man sich natürlich besser eine Funktion draus, die du mit den Koordinaten des Punktes, des Kreismittelpunktes und dem Radius parametrierst.

Kommentar von 55555555555555 ,

Danke! Dass es einfacher ist, zu sagen, ob ein Punkt innerhalb dieser beiden Kreise liegt, anstatt einer Enumeration aller Punkte ist mir klar.

Wie das funktionieren soll, kann ich mir nicht vorstellen, ich werde es aber versuchen.

Kommentar von 55555555555555 ,

Kannst du mir das mal bitte noch erklären? Dann gibts die hilfreichste Antwort :)

Wenn ich x-48 rechne, dann hab ich ja 0 ?

Kommentar von 55555555555555 ,

Wow so einfach! Jetzt hab ichs verstanden!!

Ich hab´s jetzt so gemacht (wegen der Übersichtlichkeit):

Private Function IsPointInCircle(ByVal circleX As Integer, ByVal circleY As Integer, ByVal circleRadius As Integer, _
ByVal x As Integer, ByVal y As Integer) As Boolean

Dim dx As Integer = circleX - x
Dim dy As Integer = circleY - y

Dim radiusSq As UInteger = CUInt(circleRadius ^ 2)
Dim distanceSq As UInteger = CUInt(dx * dx + dy * dy)

Return distanceSq <= radiusSq
End Function


DANKE

Antwort
von CrystalixXx, 25

Die einfachste Möglichkeit wäre mit GraphicsPath und Region zu arbeiten, wenn du bei den einfachen GDI+ Methoden des Frameworks bleiben willst. Das könnte dann ungefähr so aussehen:

Dim intersection As Region

Private Sub PictureBox1_MouseClick(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
If e.Button = Windows.Forms.MouseButtons.Left AndAlso intersection.IsVisible(e.Location) Then
Debug.WriteLine(e.Location.ToString & " ist eine Koordinate der Schnittmenge.")
End If
End Sub

Private Sub PictureBox1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality

Using p1 As New Drawing2D.GraphicsPath, p2 As New Drawing2D.GraphicsPath
p1.AddArc(New Rectangle(48, 77, 46, 46), 0, 360)
p2.AddArc(New Rectangle(52, 72, 132, 132), 0, 360)

e.Graphics.DrawPath(Pens.Red, p1)
e.Graphics.DrawPath(Pens.Red, p2)

intersection = New Region(p1)
intersection.Intersect(p2)
End Using
End Sub

Du erstellst zunächst für jedes Objekt (Kreis, Rechteck, ...) ein GraphicsPath-Objekt, dem du dann über diverse Add-Methoden unterschiedliche Geometrien hinzufügst. In dem einfachen Fall einen Kreisbogen über 360°. Danach kannst du ein Region-Objekt aus dem ersten Pfad erzeugen und über die Intersect-Methode die Schnittmenge aus diesem und den über den Parameter angegebenen Pfad ermitteln. In der MouseClick-Methode prüfst du dann mit der IsVisible-Methode, ob der Punkt enthalten ist.

Der Code sollte aber noch optimiert werden: im MouseClick sollte geprüft werden, ob "intersection" überhaupt vorhanden ist und das Erzeugen der GraphicPath-Objekte und von "intersection" sollte nicht im Paint-Ereignis geschehen, sondern in einer eigenständigen Methode, die nur einziges einmal aufgerufen wird - oder eben dann, wenn sich ein Pfad ändert.

Keine passende Antwort gefunden?

Fragen Sie die Community