[.NET] Make objects follow circular shape

Started by
5 comments, last by MaulingMonkey 13 years, 12 months ago
Hello, for the past hours, I've been searching for a way to make the 10 objects move in a circular way (in a picturebox). Ik have created the following things: - A Classe with the property's -> Name, X, Y - 10 objects are loaded into a List() - I can show these points in a picturebox But I don't know how I can move them. These objects should make a circular (or heaxagon/octagon shaped) path in the picturebox. They don't have to make perfect circles. You can compare it with leaves in a barrel. They all follow the flow (circular motion) but they don't go straight round. Is there someone who can please help me with this? Somebody, anybody?
Advertisement
two options that I see here - one, keep an angle and a radius on the objects, increase the angle over time and use sin and cos to determine x and y.
Alternatively, you can do a more physical simulation, give them a speed and accelerate them towards the center. will be difficult to get it tuned up properly.
Well, hold on. Do you need help getting them to move at all, or do you only need help figuring out how to keep them on a circular path?

Making the circle exact will be easier than making some kind of approximate artistic thing, because to make the approximate artistic thing, you first have to specify it. We know what a circle is, in the mathematical sense. "Leaves in a barrel" is intuitive, but not nearly precise enough for programming.
Quote:Original post by Zahlman
Well, hold on. Do you need help getting them to move at all, or do you only need help figuring out how to keep them on a circular path?

Making the circle exact will be easier than making some kind of approximate artistic thing, because to make the approximate artistic thing, you first have to specify it. We know what a circle is, in the mathematical sense. "Leaves in a barrel" is intuitive, but not nearly precise enough for programming.


The first problem is I can't get them to move, but today is a new day.
I'm going to try the whole thing again from the beginnen.

I'll post what I what I got.

Grts
Ok, this is what I got so far:

I got procedure to read 10 names and X / Y-coordinates and a gender:

Public Sub Inlezen()        Dim file As New FileInfo(mFile)        Dim reader As StreamReader = file.OpenText()        'aantal amoebes tellen in het txt-bestand        Do While Not reader.EndOfStream            AantalAmoebes += 1            reader.ReadLine()        Loop        reader.Close()        reader = file.OpenText()        'een lijst van amoebes creëren        mobjAmoebes = New List(Of Amoebe)        Dim lijn, naam, x, y, geslacht As String        Do While Not reader.EndOfStream            lijn = reader.ReadLine()            naam = lijn.Substring(0, 15).Trim()            x = lijn.Substring(15, 3).Trim()            y = lijn.Substring(18, 3).Trim()            geslacht = lijn.Substring(24, 1).Trim()            Dim a As Amoebe            a = New Amoebe(naam, CType(x, Integer), CType(y, Integer), geslacht)            mobjAmoebes.Add(a)        Loop


Next, a procedure to draw the "amoebes":
Public Sub Tekenen()        Dim paper As Graphics        paper = pctWereld.CreateGraphics()        paper.Clear(pctWereld.BackColor)        For Each a As Amoebe In mobjAmoebes            'verschillend geslacht = verschillende kleur            If (a.Geslacht = "Man") Then                Dim mypen As New Pen(Color.LightGreen)                paper.DrawEllipse(mypen, a.X, a.Y, straal, straal)            Else                Dim mypen As New Pen(Color.Red)                paper.DrawEllipse(mypen, a.X, a.Y, straal, straal)            End If            lstGegevens.Items.Add(a.Naam & " - " & a.X & "/" & a.Y & " - " & a.Geslacht)        Next    End Sub


Next, I have a procedure to move the objects with value 1 and draw them:

Do While (tmrCyclus.Enabled)            Dim teller As Integer = 0            For Each a As Amoebe In mobjAmoebes                Dim NewX, NewY As Integer                NewX = a.X + 1                NewY = a.Y + 1                a.X = NewX                a.Y = NewY            Next            Tekenen()            teller += 1            If teller = 3 Then                tmrCyclus.Enabled = False                Exit Do            End If        Loop


Then I got the timer:
Private Sub tmrCyclus_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrCyclus.Tick        Bewegen()    End Sub


At last I got the Form_Load
Private Sub FrmLevensspel_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load        'Om de waterkwaliteit random te laten verlopen, laat ik de keuze hiervan over aan een willekeurig gegenereerd getal        vsbWaterKwaliteit.Value = WillekeurigGetal()        WaterKwaliteit()        Inlezen()        tmrCyclus.Enabled = True        Bewegen()    End Sub


PS: The procedure "Waterkwaliteit()" is just to chose the backgroundcolor of the picturebox "pctWereld"

At this moment, my form does not show at all. When I hit the debugbutton, the form is not shown.

Any ideas? :'(
The Do while cycle (which I guess is in method "Bewegen"?) shouldn't be a cycle - what happens is that while you're in the cycle moving and drawing the new positions, you're not allowing your application thread to go and actually do the work under the covers to update the display. Or process new input.

Usually you'll use the timer to update the position and cause a drawing to occur.

(as an aside, you may want to handle the onpaint event, and put your drawing code there, and just call refresh() after you update the positions. But I think it'll work if you just call the code you have inside the do while cycle from your timer)
Quote:Original post by alexmoura
The Do while cycle (which I guess is in method "Bewegen"?) shouldn't be a cycle - what happens is that while you're in the cycle moving and drawing the new positions, you're not allowing your application thread to go and actually do the work under the covers to update the display. Or process new input.


This. In a C++ program where we process the messages ourselves, we would use such a loop, and put the message processing inside of it -- but with C# (or VB.Net), this loop exists inside of Application.Run() -- we either need to use a timer or hijack an event (such as Paint, if we call Invalidate() inside of it and are constantly redrawing)

If the timer is high frequency enough (such that a tick could still be processing when the next tick is supposed to start), or we're doing the handling from paint (where the timing is irregular at best), we probably don't want to rely on these events being spaced out at a specific interval -- instead we'll want to check how much time has passed ourselves.

A simple (C# -- sorry) example:
class MyForm : Form {    DateTime previous_frame = DateTime.Now;    public MyForm() {        Paint += (sender,args) => {            var now = DateTime.Now;            var delta = (now-previous_frame).TotalSeconds; // seconds passed since last Paint            previous_frame = now;            var paper = args.Graphics;            using ( Pen mypen = new Pen(Color.LightGreen) )            foreach ( Amoebe a in mobjAmoebes )            {                a.X += delta*10; // move 10 units per second                paper.DrawEllipse(mypen, a.X, a.Y, straal, straal);            }            Invalidate();        };    }    ...}


Of course, having said all this, I'm quite certain someone is going to link Fix Your Timestep, which goes over some of the specific disadvantages of my example.

This topic is closed to new replies.

Advertisement