Cursor binnen cirkel

Status
Niet open voor verdere reacties.

SuperABC

Gebruiker
Lid geworden
16 jul 2009
Berichten
327
Hey,

Ik heb een form, daar teken ik een cirkel... Hoe kan ik nu bepalen of de cursor zich binnen de cirkel bevindt... Voor het vierkant die de uiterkste delen vormen heb ik al de volgende code...

Code:
    Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        e.Graphics.DrawEllipse(Pens.Black, 0, 0, 100, 100)
    End Sub

    Private Sub Form1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
        Dim Mouse_Loc As New Point
        Mouse_Loc.X = e.X
        Mouse_Loc.Y = e.Y

        Dim Str As String = ""

        If Mouse_Loc.X > 0 Then
            If Mouse_Loc.X < 100 Then
                If Mouse_Loc.Y > 0 Then
                    If Mouse_Loc.Y < 100 Then
                        Str = "In circle..."
                    End If
                End If
            End If
        End If

        Me.Text = Str & "  " & Mouse_Loc.ToString()
    End Sub

Maar een cirkel is rond en niet vierkant, dus moeten de hoeken niet meegteld worden. Weet iemand hoe je dit doet?
Of dat je op basis van de X-coördinaat de, de hoogste- en laagste Y-coördinaat kunt bereken. Dus als de cursor zich op X=50 bevindt is de maximale voor Y=100 en het minimum voor Y=0... Maar heb je hier een formule voor ofso?
 
Laatst bewerkt:
Als het middelpunt van de cirkel (A,B) is.
En je muiscursor zit op (X,Y)

Dan moet je eerst de afstand bepalen van je muiscursor tot het middelpunt:
afstand = sqrt( (X - A)^2 + (Y - B)^2 )
(Stelling van Pythagoras toepassen dus)

en dan testen of die afstand <= de straal van jouw cirkel.
 
Oke, bedankt dat werkt...
Hoe kan je nagaan of je muis zich binnen een Polygon bevindt?
De polygon wordt als volgt getekend:

Code:
        Dim Points(4) As Point
        Points(0) = New Point(53, 91)
        Points(1) = New Point(53, 37)
        Points(2) = New Point(128, 37)
        Points(3) = New Point(128, 91)
        Points(4) = New Point(91, 112)

        e.Graphics.DrawPolygon(Pens.Black, Points)

Het resultaat is dus een vierkant met daar onder een driehoek. Hoe bepaal je nu of de cursor in het driehoekje is?
 
Laatst bewerkt:
Bij nader inzien toch maar wat inelkaar geprutst:
Code:
Public Class frmMain
    Private PictureHeight As Integer
    Private PictureWidth As Integer

    Private Inside As Boolean

    Private px(0 To 4) As Integer
    Private py(0 To 4) As Integer

    Private xz As Integer
    Private yz As Integer

    Private Sub BerekenZwaartepunt()
        Dim i As Integer
        xz = 0
        yz = 0
        For i = 0 To 4
            xz = xz + px(i)
            yz = yz + py(i)
        Next i
        xz = Int(xz / 5)
        yz = Int(yz / 5)
    End Sub

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PictureHeight = Me.PictureBox1.Size.Height
        PictureWidth = Me.PictureBox1.Size.Width

        px(0) = 60
        py(0) = 60
        px(1) = 240
        py(1) = 60
        px(2) = 360
        py(2) = 150
        px(3) = 180
        py(3) = 510
        px(4) = 90
        py(4) = 480

        BerekenZwaartepunt()
        Inside = False
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim i As Integer

        e.Graphics.FillRectangle(Brushes.White, 0, 0, PictureWidth, PictureHeight)

        For i = 0 To 3
            e.Graphics.DrawLine(Pens.Black, px(i), py(i), px(i + 1), py(i + 1))
        Next i
        e.Graphics.DrawLine(Pens.Black, px(0), py(0), px(4), py(4))

        e.Graphics.FillRectangle(Brushes.Black, xz - 1, yz - 1, 2, 2)

    End Sub
    Private Function SameSide(ByVal idx1 As Integer, ByVal idx2 As Integer, ByVal MouseX As Integer, ByVal MouseY As Integer) As Boolean
        Dim A As Double
        Dim B As Double

        Dim MouseLeft As Boolean
        Dim ZwaartePuntLeft As Boolean

        SameSide = True

        A = (py(idx2) - py(idx1)) / (px(idx2) - px(idx1))
        B = py(idx1) - (A * px(idx1))

        MouseLeft = (MouseY < (A * MouseX) + B)
        ZwaartePuntLeft = (yz < (A * xz) + B)

        SameSide = (MouseLeft And ZwaartePuntLeft) Or (Not (MouseLeft Or ZwaartePuntLeft))
    End Function
    Private Sub CheckInside(ByVal MouseX As Integer, ByVal MouseY As Integer)
        Dim i As Integer

        Inside = True

        For i = 0 To 3
            If Not SameSide(i, i + 1, MouseX, MouseY) Then
                Inside = False
            End If
        Next i

        If Not SameSide(0, 4, MouseX, MouseY) Then
            Inside = False
        End If

    End Sub


    Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        CheckInside(e.X, e.Y)
        If Inside Then
            MsgBox("Congratulations!!!!! You're ready to learn dart!!")
        Else
            MsgBox("Sorry   Before playing dart you ought to improve your mouse skills ...")
        End If
    End Sub
End Class
 
Ik heb van je code een class gemaakt, waardoor ik met meerdere figuren kan werken. Echter blijkt na veel klikken dat die het niet altijd goed heeft. Als je eerst eens in het tweede figuur klikt, en daarna mis, en daarna weer in de tweede, dan zegt hij dat ik in de eerste geklikt hebt?! (Gebeurt ook als je gelijk in de tweede klikt) Misschien kan iemand me helpen want ik snap totaal niet wat er fout is... De code:

Code:
Public Class Form1

    Public Regions As New List(Of Region)

    Public Shadows Class Region

        Public Inside As Boolean = False

        Public px(0 To 4) As Integer
        Public py(0 To 4) As Integer

        Public xz As Integer
        Public yz As Integer

        Public Sub BerekenZwaartepunt()
            Dim i As Integer
            xz = 0
            yz = 0
            For i = 0 To 4
                xz += px(i)
                yz += py(i)
            Next i
            xz = Int(xz / 5)
            yz = Int(yz / 5)
        End Sub

        Public Function SameSide(ByVal idx1 As Integer, ByVal idx2 As Integer, ByVal MouseX As Integer, ByVal MouseY As Integer) As Boolean
            Dim A As Double
            Dim B As Double

            Dim MouseLeft As Boolean
            Dim ZwaartePuntLeft As Boolean

            SameSide = True

            A = (py(idx2) - py(idx1)) / (px(idx2) - px(idx1))
            B = py(idx1) - (A * px(idx1))

            MouseLeft = (MouseY < (A * MouseX) + B)
            ZwaartePuntLeft = (yz < (A * xz) + B)

            SameSide = (MouseLeft And ZwaartePuntLeft) Or (Not (MouseLeft Or ZwaartePuntLeft))
        End Function

        Public Sub CheckInside(ByVal MouseX As Integer, ByVal MouseY As Integer)
            Dim i As Integer

            Inside = True

            For i = 0 To 3
                If Not SameSide(i, i + 1, MouseX, MouseY) Then
                    Inside = False
                End If
            Next i

            If Not SameSide(0, 4, MouseX, MouseY) Then
                Inside = False
            End If
        End Sub
    End Class

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim New_Region As New Region
        New_Region.px(0) = 53
        New_Region.px(1) = 53
        New_Region.px(2) = 128
        New_Region.px(3) = 128
        New_Region.px(4) = 91

        New_Region.py(0) = 91
        New_Region.py(1) = 37
        New_Region.py(2) = 37
        New_Region.py(3) = 91
        New_Region.py(4) = 112

        Regions.Add(New_Region)

        Dim New_Region1 As New Region
        New_Region1.px(0) = 136
        New_Region1.px(1) = 136
        New_Region1.px(2) = 211
        New_Region1.px(3) = 211
        New_Region1.px(4) = 174

        New_Region1.py(0) = 66
        New_Region1.py(1) = 12
        New_Region1.py(2) = 12
        New_Region1.py(3) = 66
        New_Region1.py(4) = 87

        Regions.Add(New_Region1)

        For X As Integer = 0 To Regions.Count - 1 Step +1
            Regions.Item(X).BerekenZwaartepunt()
        Next

        '53,91,53,37,128,37,128,91,91,112"
        '136,66,136,12,211,12,211,66,174,87"
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        For X As Integer = 0 To Regions.Count - 1 Step +1
            Dim Current_Region As Region = Regions.Item(X)

            Dim i As Integer

            For i = 0 To 3
                e.Graphics.DrawLine(Pens.Black, Current_Region.px(i), Current_Region.py(i), Current_Region.px(i + 1), Current_Region.py(i + 1))
            Next i
            e.Graphics.DrawLine(Pens.Black, Current_Region.px(0), Current_Region.py(0), Current_Region.px(4), Current_Region.py(4))

            'e.Graphics.FillRectangle(Brushes.Black, Current_Region.xz - 1, Current_Region.yz - 1, 2, 2)
        Next
    End Sub

    Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        For X As Integer = 0 To Regions.Count - 1 Step +1
            Dim Current_Region As Region = Regions.Item(X)
            Current_Region.Inside = False
            Current_Region.CheckInside(e.X, e.Y)

            If Current_Region.Inside = True Then
                MsgBox("Congratulations!" & vbCrLf & X.ToString, MsgBoxStyle.Exclamation)
                X = Regions.Count
            Else
                MsgBox("Miss...", MsgBoxStyle.Exclamation)
            End If
        Next
    End Sub
End Class
 
Ik zit heel kort te kijken en het eerste wat me opvalt is waarom zijn xz en yz public?
 
het zal niet liggen aan die public xz en yz...

misschien dat de naamgeving X hier roet in het eten gooit:
Code:
    Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        For X As Integer = 0 To Regions.Count - 1 Step +1
            Dim Current_Region As Region = Regions.Item(X)
            Current_Region.Inside = False
            Current_Region.CheckInside(e.X, e.Y)

            If Current_Region.Inside = True Then
                MsgBox("Congratulations!" & vbCrLf & X.ToString, MsgBoxStyle.Exclamation)
                X = Regions.Count
            Else
                MsgBox("Miss...", MsgBoxStyle.Exclamation)
            End If
        Next
    End Sub
omdat X ook al de x-coordinaat van de muis is?
 
Ik weet het al.:eek::)
Hier gaat het mis:
Code:
        Public Function SameSide(ByVal idx1 As Integer, ByVal idx2 As Integer, ByVal MouseX As Integer, ByVal MouseY As Integer) As Boolean
            Dim A As Double
            Dim B As Double

            Dim MouseLeft As Boolean
            Dim ZwaartePuntLeft As Boolean

            SameSide = True

            A = (py(idx2) - py(idx1)) / (px(idx2) - px(idx1))
            B = py(idx1) - (A * px(idx1))

            MouseLeft = (MouseY < (A * MouseX) + B)
            ZwaartePuntLeft = (yz < (A * xz) + B)

            SameSide = (MouseLeft And ZwaartePuntLeft) Or (Not (MouseLeft Or ZwaartePuntLeft))
        End Function

Ik wil hier elk van de zijden van de polygoon beschrijven door een vergelijking y = ax + b.

Maar bij een verticale lijn lukt dat niet. Er wordt dan hier door nul gedeeld:
Code:
            A = (py(idx2) - py(idx1)) / (px(idx2) - px(idx1))

(Ik snap niet dat het programma dit niet laat zien als run-time error - erg misleidend!:evil::evil: - maar dat even terzijde.)

De onderliggende wiskunde was, dat ik de vergelijking y = ax + b gebruik om te bepalen of twee punten zich elk aan dezelfde kant van een lijn bevinden.
In dit geval dus: een van de zijden van de polygoon, het zwaartepunt van de polygoon en het punt waar met de muis werd geklikt.

Maar verticale lijnen vormen een apart geval en moeten op een andere manier uitgerekend worden.

Eigenlijk weet ik ook wel hoe je bij een verticale lijn SameSide moet bepalen.

Code:
            MouseLeft = (MouseX < px(idx1))
            ZwaartePuntLeft = (xz < px(idx1))
            SameSide = (MouseLeft And ZwaartePuntLeft) Or (Not (MouseLeft Or ZwaartePuntLeft))

Dat wordt dus een if-then-else. Hoop dat dit niet al te cryptisch is:):D
 
Oke, nu werkt het volgens mij wel goed. Na >100x klikken heeft die het elke keer goed gehad. Heb er nu dit van gemaakt:

Code:
        Public Function SameSide(ByVal idx1 As Integer, ByVal idx2 As Integer, ByVal MouseX As Integer, ByVal MouseY As Integer) As Boolean
            Dim A As Double
            Dim B As Double

            Dim MouseLeft As Boolean
            Dim ZwaartePuntLeft As Boolean

            SameSide = True

            A = (py(idx2) - py(idx1)) / (px(idx2) - px(idx1))
            B = py(idx1) - (A * px(idx1))

            If (px(idx2) - px(idx1)) = 0 Then
                MouseLeft = (MouseX < px(idx1))
                ZwaartePuntLeft = (xz < px(idx1))
                SameSide = (MouseLeft And ZwaartePuntLeft) Or (Not (MouseLeft Or ZwaartePuntLeft))
            Else
                MouseLeft = (MouseY < (A * MouseX) + B)
                ZwaartePuntLeft = (yz < (A * xz) + B)

                SameSide = (MouseLeft And ZwaartePuntLeft) Or (Not (MouseLeft Or ZwaartePuntLeft))
            End If

        End Function

Bedoelde je het zo?
 
Mooie class SuperABC!

Maar ja, wat doe je als je ook polygons met een willekeurig aantal punten wilt gebruiken? Hier zit je vast aan 5 punten.
 
Inderdaad, ik had al geprobeerd om het met een X aantal punten te werken, maar dat kwam allemaal niet echt goed uit:( Wel alle 5 vervangen door X, en 4 door X - 1. Maar het zwaartepunt viel er bij de meeste dingen al buiten. Maar zoals het nu is, is het goed genoeg meer punten heb ik niet nodig.:thumb:
 
idee:

ik heb die vorige brokken tekst niet echt bekeken, (weet zelf amper iets van vb ...)

maar in't kort:
waarom splits je je willekeurig gebied niet op in kleinere stukken?
dit zal (volgens mij) altijd werken,

maar zodra je met "bizarre" figuren begint, gaat dan wel veel typwerk zijn,
 
Zo bizar is het niet hoor... Wil jij per pixel duidelijk maken welke er bijhoort of welke niet:D
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan