It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

By Jeff Lander
Gamasutra
February 10, 2000

Printer Friendly Version

 

Change Login/Pwd
Post A Job
Post A Project
Post Resume
Post An Event
Post A Contractor
Post A Product
Write An Article
Get In Art Gallery
Submit News

 


 


[Submit Letter]

[View All...]
  



[Submit Event]
[View All...]

 


[Enter Forums...]

Note: Discussion forums for Gamasutra are hosted by the IGDA, which is free to join.
 

 

 


Features

Listing 1. The Quadrant Approach
to the Bounding Box Test

 

// FIGURE OUT WHICH QUADRANT THE VERTEX IS RELATIVE TO
// THE HIT POINT

#define WHICH_QUAD(vertex,hitPos) \

   ( (vertex.x > hitPos->x) ? ((vertex.y > hitPos->y)
  ? 1 : 4) :( (vertex.y > hitPos->y) ? 2 : 3) )

// GET THE X INTERCEPT OF THE LINE FROM THE CURRENT VERTEX TO
// THE NEXT

#define X_INTERCEPT(point1, point2, hitY) \
  
(point2.x - ( ((point2.y - hitY) * (point1.x - point2.x))
  / (point1.y - point2.y) ) )

/////////////////////////////////////////////////////////////
// Procedure: PointInPoly (SUM OF ANGLES CROSSING VERSION)
// Purpose: Check if a point is inside a polygon
// Returns: TRUE if Point is inside polygon, else FALSE
/////////////////////////////////////////////////////////////

BOOL CFateView::PointInPoly(tSector *sector, tPoint2D *hitPos)
{

/// Local Variables /////////////////////////////////////////
  
short edge, first, next;
  
short quad, next_quad, delta, total;

/////////////////////////////////////////////////////////////
  
edge = first = sector->edge;
   
quad = WHICH_QUAD(m_edgelist[edge].pos, hitPos);
  
total = 0; // COUNT OF ABSOLUTE SECTORS CROSSED
  
/* LOOP THROUGH THE VERTICES IN A SECTOR */
  
do {
    
next = m_edgelist[edge].nextedge;
    
next_quad = WHICH_QUAD(m_edgelist[next].pos, hitPos);
    
delta = next_quad - quad; // HOW MANY QUADS HAVE I MOVED
    

// SPECIAL CASES TO HANDLE CROSSINGS OF MORE THEN ONE         
//QUAD

    
switch (delta) {
    
case 2:  // IF WE CROSSED THE MIDDLE, FIGURE OUT IF IT
             //WAS CLOCKWISE OR COUNTER
    
case -2: // US THE X POSITION AT THE HIT POINT TO
             // DETERMINE WHICH WAY AROUND
    
if (X_INTERCEPT(m_edgelist[edge].pos,
     m_edgelist[next].pos, hitPos->y) > hitPos->x)
      
delta = - (delta);
        
break;
    
case 3: // MOVING 3 QUADS IS LIKE MOVING BACK 1
      
delta = -1;
        
break;
    
case -3: // MOVING BACK 3 IS LIKE MOVING FORWARD 1
      
delta = 1;
        
break;
    
}
  
/* ADD IN THE DELTA */
  
total += delta;
  
quad = next_quad; // RESET FOR NEXT STEP
  
edge = next;
  
} while (edge != first);

   /* AFTER ALL IS DONE IF THE TOTAL IS 4 THEN WE ARE INSIDE */
  
if ((total == +4) || (total == -4)) return TRUE; else return FALSE;
}

_____________________________________________________________

Back to Article


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service