4 Replies - 1699 Views - Last Post: 30 October 2010 - 12:39 PM Rate Topic: -----

#1 Guest_Ron*


Reputation:

Rotation and Collision detection

Posted 15 October 2010 - 01:09 PM

I have created an object the moves around on a form, nothing fancy by any means. I am "simulating" a car driving around, so my left and right movements are Matrix Rotations. I have been trying and trying to figure this out and i think I have something of an answer to why my thoughts about it were wrong. It starts with moving in the Y direction (down).

When you rotate it basically rotates the entire coordinate plane it is being displayed on is being rotated?

All I am trying to do at this point is not allow the "car" (rectangle) to go outside the bounds of the form.
Because of the rotations, my Y coordinate of the "car" (rectangle) is always going in the positive direction.

Any information on this would be great, I can provide my code if needed.

Is This A Good Question/Topic? 0

Replies To: Rotation and Collision detection

#2 Qball522  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 86
  • Joined: 06-October 08

Re: Rotation and Collision detection

Posted 15 October 2010 - 01:11 PM

This post is mine, not sure why it posted as a quest, I was signed in.

Shrug.
Was This Post Helpful? 0
  • +
  • -

#3 Qball522  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 86
  • Joined: 06-October 08

Re: Rotation and Collision detection

Posted 15 October 2010 - 11:11 PM

No one?

:(
Was This Post Helpful? 0
  • +
  • -

#4 lfaivor21  Icon User is offline

  • New D.I.C Head

Reputation: 10
  • View blog
  • Posts: 29
  • Joined: 17-October 10

Re: Rotation and Collision detection

Posted 18 October 2010 - 10:49 AM

If you have coordinates in window space for the corners of the car you can test during each iteration of your game loop to make sure that they are within the bounds of the game. And if they aren't apply the sufficient combination of angular and translational impulse to keep it on screen. An impulse is basically just a velocity change so let's say the car is going up and right at 45 degrees and the top left corner of the car hits the edge. You'd basically want it to 'bounce' off the wall by rotating counter clockwise facing down and right while still going the same speed (magnitude of velocity vector). You can accomplish this by using the normal vector of the wall and reflecting the velocity vector over it then taking the negative of that result. After that is accomplished update the direction of the car to coincide with the new velocity. You'd probably also want to reflect the position vector as well to make it look better. Be wary sometimes this isn't so good due to the position not moving continuously but discretely so the car can end up part way through the wall and can result in multiple collisions so you might also want to keep track and see if it just collided or not and ignore the next collision with the same wall (since it's already moving away from it anyway). Another way to do it would be to give the car a radius and keep track of it as if it were a circle. Circle line collisions are much easier to work through.
Was This Post Helpful? 0
  • +
  • -

#5 Qball522  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 86
  • Joined: 06-October 08

Re: Rotation and Collision detection

Posted 30 October 2010 - 12:39 PM

Basic collision I have a grasp on. If some object occupies the same space as something else, you have a collision and handle it accordingly.

My problem is that I am new to rotations and from the method I found, you have a car that moves in only 2 directions (forward and backward). You can however turn that car and then travel still in a forward or backward motion. The way that I have handled it is as follows.

Press up arrow(car moves forward)
Press down arrow(car moves backward)
Press either left or right arrow(car rotates around its center)

Once rotated the Y position of the car it the only thing that ever gets increased or decreased.
Once you rotate, from my understanding you move the entire coordinate plane which the object is painted to. So because of that no matter what direction you rotate and move in a forward or backward motion, your car is only moving along the Y axis.

Example, The cars center starts and position 100,100, facing downward on the screen.
You move 200 units forward, it puts the cars center at 100,300.
If you rotate toward the right at 90 degrees and move the car 200 units right on the screen, one would think that you would now be at position 300,300.
That is not the case with my app. The cars center would now reside at the point 100,500. The car will in fact be 300 pixels right and 300 pixels down, from the origin or the window.

Because of the rotation your movement will never move in any X direction.

I hope this is enough info to assist me in some way. I KNOW there is something that I am failing to do or failing to relize about this.

Here, maybe this would help
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Drawing.Drawing2D;

namespace DoubleBufferTesting
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.UserPaint |
            ControlStyles.AllPaintingInWmPaint |
            ControlStyles.OptimizedDoubleBuffer, true);

            KeyPreview = true;
            Thread t = new Thread(new ThreadStart(Running));
            t.IsBackground = true;
            t.Start();
        }
        class Road
        {
            public Road()
            {

            }
            public void Draw(Graphics g)
            {
                //Main N - S Road
                g.FillRectangle(new SolidBrush(Color.Black), 175, 0, 150, 900);
                //Main N - S Road Lines
                g.DrawLine(new Pen(Color.Yellow), 246, 0, 246, 400);
                g.DrawLine(new Pen(Color.Yellow), 250, 0, 250, 400);
                g.DrawLine(new Pen(Color.Yellow), 246, 500, 246, 700);
                g.DrawLine(new Pen(Color.Yellow), 250, 500, 250, 700);
                //Main E - W Road
                g.FillRectangle(new SolidBrush(Color.Black), 300, 400, 600, 100);
                //Main E - W Road Lines
                g.DrawLine(new Pen(Color.Yellow), 325, 446, 900, 446);
                g.DrawLine(new Pen(Color.Yellow), 325, 450, 900, 450);
            }
        }
        class Box
        {
            public int X;
            public int Y;
            public int length;
            public int width;

            public int Degrees = 0;

            public System.Drawing.Drawing2D.Matrix MAT;
            public bool Rotating = false;
            public float RotateDegree;

            public Box()
            {
                length = 60;
                width = 40;
                X = 200;
                Y = 200;
                MAT = new System.Drawing.Drawing2D.Matrix();
                RotateDegree = 0;
            }
            public virtual void Draw(Graphics g)
            {
                if (Degrees == 0 && RotateDegree < 0)
                    Degrees = 360;
                Degrees = Degrees + (int)RotateDegree;
                if (Degrees == 360)
                    Degrees = 0;

                MAT.RotateAt(RotateDegree, new PointF((float)X + (.5f * width), (float)Y + (.5f * length)));
                Rotating = false;
                g.Transform = MAT;
                RotateDegree = 0;
                Point[] points = new Point[5];
                points[0] = new Point(X, Y + 62);
                points[1] = new Point(X + 40, Y + 62);
                points[2] = new Point(X + 55, Y + 150);
                points[3] = new Point(X - 15, Y + 150);
                points[4] = new Point(X, Y + 62);
                LinearGradientBrush brush = new LinearGradientBrush(new Point(X + 20, Y + 62), new Point(X + 20, Y + 150), Color.LightBlue, Color.White);
                g.FillPolygon(brush, points, FillMode.Alternate);
                g.FillRectangle(new SolidBrush(Color.Red), X, Y, width, length);
                g.FillRectangle(new SolidBrush(Color.Honeydew), X + 2, Y + 30, width - 5, length - 45);
                ////Temp Draw Center CROSS
                //g.DrawLine(new Pen(Color.Black), X, Y - 10, X, Y + 40);
                //g.DrawLine(new Pen(Color.Black), X - 10, Y, X + 10, Y);
            }
        }
        //public GDIDB.DBGraphics buffer = new GDIDB.DBGraphics();
        private Box B = new Box();
        private Road R = new Road();
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            
            Color C = System.Drawing.Color.FromArgb(0,204,102);
            Graphics g = e.Graphics;
            g.Clear(C);
            R.Draw(g);
            B.Draw(g);
        }

        private void Mine()
        {
            B.Y = 300;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Mine();
        }
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {

            if (keyData.ToString().Equals("Up"))
            {
                up = true;
            }
            if (keyData.ToString().Equals("Down"))
            {
                down = true;
            }
            if (keyData.ToString().Equals("Left"))
            {
                left = true;
            }
            if (keyData.ToString().Equals("Right"))
            {
                right = true;
            }
            Invalidate();

            return true;
        }
        public bool up = false;
        public bool down = false;
        public bool right = false;
        public bool left = false;
       
        private void Running()
        {
            while (true)
            {
                if (up)
                {
                    B.Y = B.Y + 1;
                    Invalidate();
                }
                if (down)
                {
                    B.Y = B.Y - 1;
                    Invalidate();
                }
                if (right)
                {
                    B.Rotating = true;
                    B.RotateDegree = B.RotateDegree + 5;
                    Invalidate();
                }
                if (left)
                {
                    B.Rotating = true;
                    B.RotateDegree = B.RotateDegree - 5;
                    Invalidate();
                }
                Loc();
                Thread.Sleep(10);
            }
        }
        //private void Form1_KeyDown(object sender, KeyEventArgs e)
        //{
        //    if(e.KeyCode == Keys.Up)
        //        up = true;
        //   if(e.KeyCode == Keys.Left)
        //        left = true;
        //    if(e.KeyCode == Keys.Down)
        //        down = true;
        //   if(e.KeyCode == Keys.Right)
        //        right = true;
        //}
        public void Loc()
        {
            try
            {
                Invoke((MethodInvoker)delegate
                {
                    lblX.Text = B.X.ToString();
                    lblY.Text = B.Y.ToString();
                    lblDegrees.Text = B.Degrees.ToString();
                });
            }
            catch (Exception e)
            { }
        }
        public void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            
        }
        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {

            if (e.KeyCode == Keys.Up)
            {
                up = false;
            }
            if (e.KeyCode == Keys.Left)
            {
                left = false;
            }
            if (e.KeyCode == Keys.Down)
            {
                down = false;
            }
            if (e.KeyCode == Keys.Right)
            {
                right = false;
            }

        }
    }
}



Was This Post Helpful? 0
  • +
  • -

Page 1 of 1