我设计的这个程序通过执行少量的数学向量运算来解决两个向量碰撞的问题。
很希望这个程序能对那些正在进行2D图形程序设计并需要一个算法去解决两个对象碰撞的问题的朋友有用,这个程序并没有依靠著名的被许多图形对象定义的"bounding box"算法,你只需要简单的执行这个类来定义一组向量,无论何时图形对象被移动了,你都可以调用这些为对象设置了的命令。
这是个仍然在检验的代码,但是多次的测试显示如果向量在一个点相遇或者交叉,那么向量通过比较就会显示他们已经相遇。
这个类不处理对象内部的形态差异。如果一个对象完全处在了另一个对象的内部那么向量碰撞可能失败,然儿,这可能对那些要执行对象间跳跃的程序有用。
[纯文本代码]
-
#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 ( );
-
-
//Checking for intersection between the first triangle with the second
-
(tri == otherTri );
-
//Checking for intersection between the first triangle with the third
-
(tri == finalTri );
-
//Checking for intersection between the secondtriangle with the third
-
(otherTri == finalTri );
-
cout << "/n" << endl;
-
finalTri. Set ( 1.5, 2, otherPoints );
-
cout << "Setting the 3rd triangle to same coords as 2nd.../n" << endl;
-
-
//Checking for intersection between the first triangle with the second
-
(tri == otherTri );
-
//Checking for intersection between the first triangle with the third
-
(tri == finalTri );
-
//Checking for intersection between the secondtriangle with the third
-
(otherTri == finalTri );
-
cin. get ( );
-
return 0;
-
}