Thread: (C#) Ray->Box intersection

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    244

    (C#) Ray->Box intersection

    hi everyone!
    I'm looking for a ray -> box intersection function for my raytracer. if anyone knows one or has one, please let me know.

    here is the one i have yet (ported from other code). the problem is, that no picked coordinates and normals are returned.

    variables:
    XYZ - Cube positions
    Width, Height, Depth - Cube size
    Code:
    public bool Pick(double ray_x, double ray_y, double ray_z, double ray_nx, double ray_ny, double ray_nz)
    		{
    			double bminx = X - Width / 2;
    			double bminy = Y - Height / 2;
    			double bminz = Z - Depth / 2;
    			double bmaxx = X + Width / 2;
    			double bmaxy = Y + Height / 2;
    			double bmaxz = Z + Depth / 2;
    			double txmin = 0, txmax = 0, tymin = 0, tymax = 0, tzmin = 0, tzmax = 0;
    
    			if (ray_nx > 0)
    			{
    				txmin = (bminx - ray_x) / ray_nx;
    				txmax = (bmaxx - ray_x) / ray_nx;
    			}
    			else
    			{
    				txmin = (bmaxx - ray_x) / ray_nx;
    				txmax = (bminx - ray_x) / ray_nx;
    			}
    			if (ray_ny > 0)
    			{
    				tymin = (bminy - ray_y) / ray_ny;
    				tymax = (bmaxy - ray_y) / ray_ny;
    			}
    			else
    			{
    				tymin = (bmaxy - ray_y) / ray_ny;
    				tymax = (bminy - ray_y) / ray_ny;
    			}
    			if (txmin > tymax || tymin > txmax) return false;
    			if (tymin > txmin) txmin = tymin;
    			if (tymax < txmax) txmax = tymax;
    			if (ray_nz > 0)
    			{
    				tzmin = (bminz - ray_z) / ray_nz;
    				tzmax = (bmaxz - ray_z) / ray_nz;
    			}
    			else
    			{
    				tzmin = (bmaxz - ray_z) / ray_nz;
    				tzmax = (bminz - ray_z) / ray_nz;
    			}
    			if (txmin > tzmax || tzmin > txmax) return false;
    
    			return true;
    		}
    thanx in advance

  2. #2

    Join Date
    May 2005
    Posts
    1,042
    If you instead construct your box out of 6 planes, each defined by a normal the plane's distance from the origin, then you can use the Quake3 brush collision test. It'll return the XYZ of the collision point as well as the normal.

    You do not need the box's XYZ position center if you have each plane's distance from the origin.


    This is described in detail in this site:
    http://www.devmaster.net/articles/quake3collision/

    You can basically skip everything and just go down to the 'checkbrush' function. In Quake3 a brush can be any ridiculously complicated set of convex planes, a closed box is the simplest brush.

    From the site:
    Code:
    void CheckBrush( object *brush )
    {
        float startFraction = -1.0f;
        float endFraction = 1.0f;
        boolean startsOut = false;
        boolean endsOut = false;
    
        for (int i = 0; i < brush->numSides; i++)
        {
            object *brushSide = &BSP.brushSides[brush->firstSide + i];
            object *plane = &BSP.planes[brushSide->planeIndex];
    
            float startDistance = DotProduct( inputStart, plane->normal ) -
                                  plane->distance;
            float endDistance = DotProduct( inputEnd, plane->normal ) -
                                plane->distance;
    
            if (startDistance > 0)
                startsOut = true;
            if (endDistance > 0)
                endsOut = true;
    
            // make sure the trace isn't completely on one side of the brush
            if (startDistance > 0 && endDistance > 0)
            {   // both are in front of the plane, its outside of this brush
                return;
            }
            if (startDistance <= 0 && endDistance <= 0)
            {   // both are behind this plane, it will get clipped by another one
                continue;
            }
    
            // MMM... BEEFY
            if (startDistance > endDistance)
            {   // line is entering into the brush
                float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
                if (fraction > startFraction)
                    startFraction = fraction;
            }
            else
            {   // line is leaving the brush
                float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
                if (fraction < endFraction)
                    endFraction = fraction;
            }
        }
    }
    Last edited by BobMcGee123; 12-10-2008 at 12:48 PM.
    I'm not immature, I'm refined in the opposite direction.

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    umh. i don't understand that code...maybe it's because it's c++?
    besides, where has all the calculation gone?
    do you have any references for code which is easily convertable to my c# raytracer or even c# code?

  4. #4
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    You don't need that code in particular, here's the idea.

    Write a function that checks if a ray intersects a (bounded) plane. This is the most straight forward type of intersection to check for, search the web and you'll find many examples.

    From your box, construct 6 bounded planes (after all, that's what a box is). If the ray intersects any of those planes, it intersects your box.

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    that is what i tried after i realized that the web couldnt give me a proper solution. my result was very buggy and slow

  6. #6
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    If checking the intersection with 6 planes is slow there's something very wrong somewhere...

  7. #7
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    i'm actually not a math genius. i'm a good programmer, but for the maths, i'm still advanced only...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help designing a recursive function.
    By broli86 in forum C Programming
    Replies: 3
    Last Post: 07-24-2008, 12:45 PM
  2. Help with finding the intersection of 2 strings
    By hay_man in forum C++ Programming
    Replies: 5
    Last Post: 09-30-2006, 06:30 PM
  3. about intersection in the vector....any idea?
    By peter_hii in forum C++ Programming
    Replies: 3
    Last Post: 09-22-2006, 12:00 AM
  4. how to compute set intersection efficiently?
    By George2 in forum C Programming
    Replies: 4
    Last Post: 06-02-2006, 09:06 AM
  5. Ray tracer and collision detection
    By hdragon in forum Game Programming
    Replies: 31
    Last Post: 01-19-2006, 11:09 AM