Sunday, June 24, 2012

Updated collision detection with ray casting that actually functions but needs more testing!

Alright, so there might be good news...From what I can tell my ray casting algorithm is working so far, however the movement is still very umm....bad.  But, I'm quite glad to see my ray casting algorithm works.  I'll be working on it some more for initial circle collision, then the ray casting detection for more accurate collision detection.  At the moment I'm watching Psych...I'm on season 2 so far so good.  Rather silly, as always, but I never can focus on my programming...I went ahead and posted a few lines of code from my work.  If any readers want to comment on the code, shoot me a comment, I'll read over it and reply.  I'd be glad to hear about things i can do to improve.  :-)

Basic method for checking if a point intersects a segment.  Edge class contains 2 Vector2's, p1 and p2, which act as a 2D point in electronic nether-space.


        protected bool RayIntersectsSegment(Vector2 p, Edge edge, Vector2 world)
        {
            //This method is strictly used for checking if the specific point p intersects the edges points.
            //First we need to find the 2 vector values a and b.  a must be below b on the y axis.
            Vector2 a;
            Vector2 b;
            float red;
            float blue;

            //Check which one's above and which one's below.  And then increment them by the world translation.  It's very important that we do that...
            if (edge.p1.Y >= edge.p2.Y)
            {
                a = edge.p2 + world;
                b = edge.p1 + world;
            }
            else
            {
                a = edge.p1 + world;
                b = edge.p2 + world;
            }

            if (p.Y == a.Y || p.Y == b.Y)
            {
                p.Y += 2;   //Magic number used to increment y just a little bit to get it out of the path of the vertex itself.
            }
            if (p.Y < a.Y || p.Y > b.Y)
            {
                return false;
            }
            else if (p.X > Math.Max(a.X, b.X))
            {
                return false;
            }
            else
            {
                if (p.X < Math.Min(a.X, b.X))
                {
                    return true;
                }
                else
                {
                    if (a.X != b.X)
                    {
                        red = (b.Y - a.Y) / (b.X - a.X);
                    }
                    else
                    {
                        red = float.PositiveInfinity;
                    }
                    if (p.X != a.X)
                    {
                        blue = (p.Y - a.Y) / (p.X - a.X);
                    }
                    else
                    {
                        blue = float.PositiveInfinity;
                    }

                    if (blue >= red)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }

This method is called in this series of loops here.  The object vertices is a List of vertices, and the object boEdges contains the list of Edge objects in the other polygonal object.


                    foreach (Vector2 cp in vertices)
                    {
                        int bcounter = 0;
                        Vector2 cpw = cp + parent.position + parent.origin + offset;    //Translated to the world.
                        Vector2 oWorld = other.position + other.origin + box.offset;

                        //then check for every edge in oe.
                        foreach (Edge oe in boEdges)
                        {
                            if (RayIntersectsSegment(cpw, oe, oWorld))
                            {
                                bcounter++;
                            }
                        }

                        if (bcounter % 2 > 0)
                        {
                            //If the counter turns out to be odd, return true.
                            return true;
                        }
                    }

If I got anything seems wrong, give me a holler, I'm all ears.  :-D  Also, this was created in C# using the XNA Framework.

No comments:

Post a Comment