This is a program I designed that implements a little bit of vector-math to determine the collision between 2 vectors.

Hopefully this program will be useful to those out there designing 2D graphics programs and need a better solution to determining graphical object-to-object collisions when two objects meet, without having to rely on the famous "bounding box" that many graphical objects are defined by. One can simply implement this class and define their object to consist of these vectors and call upon the Set command for each vector whenever the graphical object is moved.

This is still experimental code, but the tests show that if the vectors meet at a point or intersect then there will be an Intersection met notice when the vectors are compared.

This class does NOT deal with the difference of shapes within shapes. If a shape is fully inscribed within another shape then a vector collision may fail. However, this may be useful if programs want to implement objects bouncing within other objects.

137 Views
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <iomanip>

/*
 *A Simple collision-detecting class
 *Made by Alex Edwards, modified by Ancient Dragon
 **/
using namespace std;

class Point;
class Triangle;
class P2DVector;

class Point{     
      private:
             double xP;
             double yP;
             
      public:
             Point(double x, double y){
                   xP = x;
                   yP = y;
             };
             Point() {xP = 0; yP = 0;}
             void Set(double x,double y) {xP = x; yP = y;}
             double getX(){return xP;};
             double getY(){return yP;};
             void showCoord(){
                  cout << "(" << getX() << ", " << getY() << ")" << endl;
             };
};

/*
 *class P2DVector
 *Named P2DVector to differentiate between the vector class and 3D vectors.
 **/
class P2DVector{
      private:
             Point points[2]; 
      
      public:
             P2DVector(Point& first, Point& second){
                      points[0] = first;
                      points[1] = second;        
             };
             P2DVector() {points[0] = Point(0,0); points[1] = Point(0,0); }
             void Set(Point& first, Point& second){
                      points[0] = first;
                      points[1] = second;        
             };
             double getXDir(){
                    return (points[1].getX() - points[0].getX());
             };
             double getYDir(){
                    return (points[1].getY() - points[0].getY());
             };
             double magnitude(){
                    return sqrt( (pow( points[1].getX() - points[0].getX() ,2) 
                                 +pow(points[1].getY() - points[0].getY() ,2)));
             };
             Point startPoint(){
                   Point p(points[0].getX(), points[0].getY());
                   return p;
             };
             Point endPoint(){
                   Point p(points[1].getX(), points[1].getY());
                   return p;
             };
             P2DVector unitP2DVector(){      
                    Point unitPoint[2];
                    unitPoint[0].Set(points[0].getX() / magnitude(), points[0].getY() / magnitude());
                    unitPoint[1].Set(points[1].getX() / magnitude(), points[1].getY() / magnitude());
                    P2DVector temp (unitPoint[0], unitPoint[1]);
                    return temp;
             };
             void displayLocation(){
                  cout << "This P2DVector Starts-> " << "" << points[0].getX() << ", " << points[0].getY();
                  cout << "\nEnds-] " << "\t\t\t" << points[1].getX() << ", " << points[1].getY();
                  cout << "\nDirection: "<< "\t\t" << "<" << getXDir() << ", " << getYDir() <<">";
                  cout << "\nContains magnitude: \t" << magnitude() << "\n" << endl;
             };
             bool operator==(P2DVector &other){
                  double otherXDirection = other.getXDir();
                  double otherYDirection = other.getYDir();
                  double xDirection = getXDir();
                  double yDirection = getYDir();
                  
                  //The statements below are a solution to a system of equations for vector-to-vector collisions
                  double time2 = ((other.startPoint().getY()-startPoint().getY())-
                  (((other.getYDir())*((other.startPoint().getX())-(startPoint().getX())))
                  /(other.getXDir())))/((getYDir())-((other.getYDir())*((getXDir())/(other.getXDir()))));    
                              
                  double time1 =  ((startPoint().getX() - other.startPoint().getX())
                                  + ((getXDir()) * (time2)))/(other.getXDir());
                                   
                 return time1 >= 0 && time1 <=1 && time2 >= 0 && time2 <=1;
             };
};

/*
 *A Sample shape that utilizes the vectors
 **/
class Triangle{
      private:
              Point coordinates[3], shortestCollision[3];
              P2DVector innerVectors[3], outterVectors[6];
      
      public:
             Triangle(double xLoc, double yLoc, Point points[3]){       
                  Set(xLoc, yLoc, points);
             };
             void Set(double xLoc, double yLoc, Point points[3]){         
                  for(int i = 0; i < 3; i++)
                        coordinates[i].Set( xLoc + points[i].getX(), yLoc + points[i].getY());    
                                          
                  outterVectors[0].Set(coordinates[0], coordinates[1]);
                  outterVectors[1].Set(coordinates[1], coordinates[2]);
                  outterVectors[2].Set(coordinates[2], coordinates[0]);
                  outterVectors[3].Set(coordinates[1], coordinates[0]);
                  outterVectors[4].Set(coordinates[2], coordinates[1]);
                  outterVectors[5].Set(coordinates[0], coordinates[2]);                  
                  
                  shortestCollision[0].Set(outterVectors[1].startPoint().getX() 
                  + ((outterVectors[1].getXDir() ) / 2),outterVectors[1].startPoint().getY() 
                  + ((outterVectors[1].getYDir() ) / 2));
                  innerVectors[0].Set(coordinates[0], shortestCollision[0]);
                  
                  shortestCollision[1].Set(outterVectors[2].startPoint().getX() 
                  + ((outterVectors[2].getXDir() ) / 2), outterVectors[2].startPoint().getY() 
                  + ((outterVectors[2].getYDir() ) / 2));
                  innerVectors[1].Set(coordinates[1], shortestCollision[1]);
                  
                  shortestCollision[2].Set(outterVectors[0].startPoint().getX() 
                  + ((outterVectors[0].getXDir() ) / 2), outterVectors[0].startPoint().getY() 
                  + ((outterVectors[0].getYDir() ) / 2));
                  innerVectors[2].Set(coordinates[2], shortestCollision[2]);                                 
             };             
                                     
             void displayParameters(){
                  cout << "This triangle is defined by the points/vectors (in this order):\n" << flush;
                  for(int i = 0; i < 3; i++){
                          coordinates[i].showCoord();
                          outterVectors[i].displayLocation();
                          cout << "\n" << flush;
                  }
             };
             Point *getPoints(){
                   return coordinates;
             };
             P2DVector *getInnerVectors(){
                   return innerVectors;
             }
             P2DVector *getOutterVectors(){
                   return outterVectors;
             }        
             bool operator==(Triangle &other){
                  P2DVector myVectors[] = {getOutterVectors()[0], getOutterVectors()[1], 
                                           getOutterVectors()[2], getOutterVectors()[3], 
                                           getOutterVectors()[4], getOutterVectors()[5]};                                           
                                           
                  P2DVector rogueVectors[] = {other.getOutterVectors()[0], other.getOutterVectors()[1], 
                                           other.getOutterVectors()[2], other.getOutterVectors()[3], 
                                           other.getOutterVectors()[4], other.getOutterVectors()[5]};                                         
                  
                  for(int i = 0; i < 6; i++){
                          for(int j = 0; j < 6; j++){
                                  if(myVectors[i] == rogueVectors[j]){
                                      cout << "Intersection met!" << endl;
                                      return true;
                                  }
                          }
                  }
                  cout << "No intersection met!" << endl;
                  return false;
             };                         
};

/*
 *Tests the shapes, which are triangles in this case, for a collision.
 **/
int main(int argc, char *argv[]){
    Point myPoints[3], otherPoints[3], finalPoints[3];
    myPoints[0].Set(0, 0), myPoints[1].Set(2, 2), myPoints[2].Set(2, 1);
    otherPoints[0].Set(0, 0), otherPoints[1].Set(0, 1), otherPoints[2].Set(1, 0);
    finalPoints[0].Set(0, 0), finalPoints[1].Set(1, 1), finalPoints[2].Set(1, 0);
    Triangle tri(0, 2, myPoints), otherTri(1.5, 2, otherPoints), finalTri(2, 2, finalPoints);
    
    tri.displayParameters();
    otherTri.displayParameters();
    finalTri.displayParameters();
    
    (tri == otherTri); //Checking for intersection between the first triangle with the second
    (tri == finalTri); //Checking for intersection between the first triangle with the third
    (otherTri == finalTri); //Checking for intersection between the secondtriangle with the third
    
    cout << "\n" << endl;
    finalTri.Set(1.5, 2, otherPoints);
    cout << "Setting the 3rd triangle to same coords as 2nd...\n" << endl;
    
    (tri == otherTri); //Checking for intersection between the first triangle with the second
    (tri == finalTri); //Checking for intersection between the first triangle with the third
    (otherTri == finalTri); //Checking for intersection between the secondtriangle with the third    
    
    cin.get();
    return 0;
}
About the Author

I think I finally understand what makes an individual a great programmer.

It's not the degree, and it's not the job...

...it's the discipline that makes an individual a great programmer.

I know of many people at Daniweb that did not go to college and still became great programmers. This is because they had the [u]discipline[/u] to improve their ability and familiarity with their understanding of programming technologies.


I'd like to thank these individuals, and many others who helped me since I came here:


[Note: Individuals with Professor next to their name were a huge influence to my way of thinking.]

Professor Narue (Truly a great, and very inspirational Software Engineer! )
Professor AD [Ancient Dragon] ( An Expert Programmer who knows how to turn complex problems into practical solutions. /salute )
Professor Ezzaral (Another very inspirational person! )
Professor Radical Edward ( Inspirational and absolutely Admirable! You rock!!! Whoo! XD)
Salem (Though strict, very knowledgeable programmer)
~s.o.s~ (Respectable Designer)
Masijade (Backdoor programmer /salute)
stephen84
sciwizeh (Programming Prodigy! =) )
williamhemsworth (Programming Prodigy/ Lil Bro! =P )
VernonDozier (Excellent Mathematician/Algorithm Designer )
Duoas (Very analytical Algorithmic Individual with in-depth knowledge of assembly/C++ languages )
ArkM (Bright thinker and experienced programmer)

More to come! O_O