EagleGrant
EagleGrant

Reputation: 20

Detecting when bounds of a rotating circle have hit a square

I am having trouble attempting to detect when a circle, that is following a point in a circle, has hit a label. When it hits the label, I want the label to go to the top right of the screen. So far, it will draw the circle, and it goes around the point forever, but its going right through the label, without the label being moved to the top left. Here's my code.

    Public Sub circleDetection(circle As Rectangle)
        If Label1.Bounds.IntersectsWith(circle) Then
            Label1.Top = 0
            Label1.Left = 0
            MsgBox("you DIED!")
        End If
    End Sub

Private WithEvents TMcircle As New Timer
    Dim SunCentre As New Point(300, 300)
    Dim OrbitRadius As Integer = 150
    Dim PlanetDiameter As Integer = 10
    Dim Planet As New Rectangle(OrbitRadius - PlanetDiameter \ 2, PlanetDiameter \ 2, PlanetDiameter, PlanetDiameter)
    Dim Angle As Single
    Private Sub Tmr_Tick(sender As Object, e As System.EventArgs) Handles TMcircle.Tick
        Angle += 1
        Invalidate()
        circleDetection(Planet)
    End Sub
    Public Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        ' draw center
        e.Graphics.TranslateTransform(SunCentre.X, SunCentre.Y)
        ' draw circle
        e.Graphics.RotateTransform(Angle)
        e.Graphics.FillEllipse(Brushes.Blue, Planet)
    End Sub

I have attempted to draw a secondary circle where the angle leads to, but this has failed to work as I do not have the x and y coordinates of the rotated circle. It didn't fail to run, but nothing showed up no matter how big I made it.

Upvotes: 0

Views: 84

Answers (1)

Idle_Mind
Idle_Mind

Reputation: 39122

You use the Matrix class to perform the same operations (translate and rotate) on the planet's center point that you do in the Paint() event. Then you build a rectangle from that transformed point and you now have a rectangle representing the planet in the same coordinate system as that of the Label (with respect to the Forms origin in the top left). Now we can simply use the Rectangle.IntersectsWith() method as expected to test for a collision.

Example code:

Public Class Form1

    Private WithEvents TMcircle As New Timer

    Dim Angle As Single
    Dim SunCentre As New Point(300, 300)
    Dim SunRadius As Integer = 50

    Dim OrbitRadius As Integer = 150
    Dim PlanetDiameter As Integer = 10
    Dim PlanetRadius As Integer = PlanetDiameter / 2
    Dim PlanetCentre As New Point(OrbitRadius - PlanetRadius, 0)

    Dim M As New Drawing2D.Matrix

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        TMcircle.Interval = 50
        TMcircle.Enabled = False
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        TMcircle.Start()
    End Sub

    Private Sub Tmr_Tick(sender As Object, e As System.EventArgs) Handles TMcircle.Tick
        Angle += 2
        Invalidate()
        circleDetection()
    End Sub

    Public Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        ' draw sun
        e.Graphics.TranslateTransform(SunCentre.X, SunCentre.Y)
        Dim rc As New Rectangle(New Point(0, 0), New Size(1, 1))
        rc.Inflate(SunRadius, SunRadius)
        e.Graphics.FillEllipse(Brushes.Yellow, rc)

        ' draw planet
        e.Graphics.RotateTransform(Angle)
        rc = New Rectangle(PlanetCentre, New Size(1, 1))
        rc.Inflate(PlanetRadius, PlanetRadius)
        e.Graphics.FillEllipse(Brushes.Blue, rc)
    End Sub

    Public Sub circleDetection()
        M.Reset()
        M.Translate(SunCentre.X, SunCentre.Y)
        M.Rotate(Angle)

        Dim points() As Point = {PlanetCentre}
        M.TransformPoints(points)

        Dim planetRC As New Rectangle(points(0), New Size(1, 1))
        planetRC.Inflate(PlanetRadius, PlanetRadius)

        If planetRC.IntersectsWith(Label1.Bounds) Then
            Label1.Top = 0
            Label1.Left = 0
            MessageBox.Show("you DIED!")
        End If
    End Sub

End Class

Here it is in action:

enter image description here

Upvotes: 1

Related Questions