Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move a rectangle using angles

I need to move a rectangle using angles. Actually I want to change the direction of my moving rectangle when it reaches the location I have given in my code in if statement!

I just need the way I can find out how to move my rectangle at 60, 30, 60, 120, 150, 270 degrees!

Suppose that if

          circle.Y>=this.Height-80

See this: enter image description here

I really actually need to change the direction of rectangle movement using angles! so that at certain location reaches I can change the rectangle direction according to angle of my own choice! such that:

if(circle.Y>=this.Height-80)
    move in the direction of 90 degrees

if(circle.X>=this.Width-80)
    move in the direction of 60 degree

as you can see in the screen shot!

What I have been trying is:

public partial class Form1 : Form
{
    Rectangle circle;
    double dx = 2;
    double dy = 2;

    public Form1()
    {
        InitializeComponent();
        circle = new Rectangle(10, 10, 40, 40);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Refresh();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.FillEllipse(new SolidBrush(Color.Red), circle);
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        circle.X += (int)dx;
        circle.Y += (int)dy;
        if (circle.Y>=this.Height-80)
        {
            dy = -Math.Acos(0) * dy/dy; //here i want to change the direction of circle at 90 degrees so that it should go up vertically straight with same speed
        }
        this.Refresh();
    }
}

The Problem is that I have been trying changing my conditions to:

dy = -Math.Asin(1) * dy;
dx = Math.Acos(0) * dx ;

but in both cases nothing is happening and the direction remains same! I just want to move the circle in inverted upward direction at 90 degrees when it reach at

circle.Y>=this.Height-80
like image 819
Java Nerd Avatar asked Jun 02 '14 15:06

Java Nerd


3 Answers

You need to draw the rectangle again to some image for it to display. I created this code for moving and drawing rectangle on pictureBox1, using your already defined circle-rectangle:

Moving the rectangle:

public void MoveRectangle(ref Rectangle rectangle, double angle, double distance)
{
   double angleRadians = (Math.PI * (angle) / 180.0);
   rectangle.X = (int)((double)rectangle.X - (Math.Cos(angleRadians) * distance));
   rectangle.Y = (int)((double)rectangle.Y - (Math.Sin(angleRadians) * distance));
}

Drawing the rectangle and displaying it in the PictureBox:

public void DrawRectangle(Rectangle rectangle)
{
   Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
   using (Graphics g = Graphics.FromImage(bmp))
   {
      g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
      g.FillEllipse(new SolidBrush(Color.Red), rectangle);
   }
   pictureBox1.Image = bmp;
}

Demo it with a button click:

private void Button1_Click(object sender, EventArgs e)
{
   MoveRectangle(ref circle, 90, 5);
   DrawRectangle(circle);
}
like image 137
W0lfw00ds Avatar answered Nov 07 '22 19:11

W0lfw00ds


Math.Asin(1) * dy is a constant value. Thus, you should use, for example, an instance variable that increments in each Tick of your timer.

...And *dy/dy is irrelevant.

public partial class Form1 : Form
{
    Rectangle circle;
    double dx = 2;
    double dy = 2;
    acum=0; //the new variable

...

private void timer_Tick(object sender, EventArgs e)
    {
        circle.X += (int)dx;
        circle.Y += (int)dy;
        if (circle.Y>=this.Height-300)
        {
            dy = -Math.Acos(acum); 
            acum+=1; //your accumulator
        }
        this.Refresh();
    }
like image 35
Nicolas Castro Avatar answered Nov 07 '22 19:11

Nicolas Castro


acos and asin are the inverse of sin and cos so the output of those two functions is an angle (usually in radians). This makes the code incorrect.

I strongly suggest that you read up on vector and matrix maths as using Euler angles can get quite messy.

So, you will have a position vector P and a movement vector M and the current position is:

 P' = P + M.t

where t is time, P is the original position and P' is the current position.

Then, when you want to change direction, you create a rotation matrix and multiply the movement vector M by this rotation matrix.

The advantage here is that you can step from a 2D system to a 3D system by adding a Z component to your vectors and increasing the size of your matrices.

like image 32
Skizz Avatar answered Nov 07 '22 17:11

Skizz