Reputation: 165
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?
Upvotes: 0
Views: 2149
Reputation: 8459
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();
}
Upvotes: 1
Reputation: 17470
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:
Upvotes: 4