0
votes

I know you can change a control's x/y location at runtime and I can use a timer to move it up/down/left/right/diagonally but how can you programatically move it in a circle?

For example, if I had a PictureBox control at the 12 o'clock position on my main form, can I move that picture box in a circle, finishing at its start position, on a button click?

2
Would you like to elaborate on how I would do that? - iajs
If you can move a control vertically and horizontally, you can also move it in a circle :) - Sergey Kalinichenko
Yes I know that, it's the logic of it that's the hard part. That's why I'm asking for help. - iajs

2 Answers

4
votes

Use sinus and cosinus functions.

Look at that for example.

A concrete C# example exists here. In case that the link will not exist some day, here is the source code for drawing 25 increasing radius circles on a form:

void PutPixel(Graphics g, int x, int y, Color c)
{
      Bitmap bm = new Bitmap(1, 1);
      bm.SetPixel(0, 0, Color.Red);
      g.DrawImageUnscaled(bm, x, y);
}

private void Form1_Paint(object sender, PaintEventArgs e)
{  
      Graphics myGraphics = e.Graphics;

      myGraphics.Clear(Color.White);
      double radius = 5;
      for (int j = 1; j <= 25; j++)
      {
            radius = (j + 1) * 5;
            for (double i = 0.0; i < 360.0; i += 0.1)
            {
                double angle = i * System.Math.PI / 180;
                int x = (int)(150 + radius * System.Math.Cos(angle));
                int y = (int)(150 + radius * System.Math.Sin(angle));

                PutPixel(myGraphics, x, y, Color.Red);
            }
      }
      myGraphics.Dispose();
}

Result:

enter image description here

1
votes

I've written a small class deriving from PictureBox which should let you achieve your result easily enough. Everytime you call RotateStep its location will change accordingly. Angle and speed are expressed in radians, distance in pixels.

class RotatingPictureBox : PictureBox
{
    public double Angle { get; set; }
    public double Speed { get; set; }
    public double Distance { get; set; }

    public void RotateStep()
    {
        var oldX = Math.Cos(Angle)*Distance;
        var oldY = Math.Sin(Angle)*Distance;
        Angle += Speed;
        var x = Math.Cos(Angle)*Distance - oldX;
        var y = Math.Sin(Angle)*Distance - oldY;
        Location += new Size((int) x, (int) y);
    }
}

Sample usage:

public Form1()
{
    InitializeComponent();
    var pictureBox = new RotatingPictureBox
    {
        Angle = Math.PI,
        Speed = Math.PI/20,
        Distance = 50,
        BackColor = Color.Black,
        Width = 10,
        Height = 10,
        Location = new Point(100, 50)
    };
    Controls.Add(pictureBox);
    var timer = new Timer {Interval = 10};
    timer.Tick += (sender, args) => pictureBox.RotateStep();
    timer.Start();
}