OBB algorithm implementation of game collision (Java code Implementation)

Source: Internet
Author: User
Tags gety


Company Business needsGame 2D model has a circle and a rectangle, judging the collision is the detection: 1. Whether the circle is intersecting with the Circle 2. Whether the circle intersects with the rectangle3. Whether the rectangle and rectangle intersect     first understand the principle to be realized, in order to have ideas to write codeThe 1th best judgment is whether the rectangle of the two circle center points is less than the sum of the radii of the two circles.2nd a tangled me, but it is not difficult to first look at the picture circle and the rectangle relationship has 4 kinds of situations, such as
As long as the distance between the center of the rectangle 4 is less than the radius of the circle or the center of the rectangle in the rectangular they intersect, but also to determine the center of the rectangle is to prevent the fourth picture above the special case the center to the edge of the distance has the following two cases
Two arrows indicate the distance from the point to the line segment, the second case is a special case 3rd judgment, there are several cases
I find that there is a rule that the two rectangular intersection must have a vertex in the other side of the graph to determine whether the rectangle contains a point this simple: as long as the point to the rectangle 4 and the distance of the sum is equal to the length and width of the rectangle and (high school mathematics knowledge) But judging above these is not to say the realization of the end, Game on performance requirements, and there are corresponding algorithms, Aabb,obb algorithm I only speak OBB collision

Directional bounding box (oriented bounding box), referred to as OBB. The directional bounding box is similar to AABB, but has directionality, can be rotated, and AABB cannot be rotated. As shown in 3.



Determine if two graphs (convex edges) are absent: there must be a straight line that allows the projection of these two graphs to be disjoint (in other words: As long as a straight line can separate them out) as

Judgment formula:be> (bc+de) = (1/2AC+1/2DF) =1/2 (AC+DF)---"BE>1/2 (AC+DF) can be released two rectangles are separated;is two rectangles, O1 and O2 are the center of two rectangles respectively, X line is a line parallel to A1A2, you can think of him as Axis X, where x is perpendicular to the Y line, it is obvious that a line y divides two rectangles so the two rectangles are disjoint because A1A2 is parallel to the X axis, So the length of the projection of the rectangle 1 in the linear x-axis is the line of AC, the projection of the rectangle 2 on the x-axis is DF, as long as the AC and DF are judged not to intersect, there must be a straight line to separate them out, in the Y axis there is a more simple method, which is the center of the two rectanglesO1o2the projection is greater than two rectangles in the x-axis of the projection of the absolute value of half and O1o2 on the x-axis of the projection for be as long as the Judge be> (bc+de) = (1/2AC+1/2DF) =1/2 (AC+DF) is the two rectangles on the x-axis (also equivalent to the linear A3A4, A1A2) does not intersect the projection of theThe x-axis is not really the x-axis, I just make it clear to everyone. Because the rectangle is a regular graph, as long as they detect the rectangle each side of the vertical line projection can be, two rectangles a total of 8 edges, because each rectangle has 22 parallel, and 22 vertical, so we only need to detect two rectangles to each rectangle adjacent two sides of the projection is intersecting, As long as 4 tests have one of the two rectangular projections without intersection, you can tell that the two rectangles do not intersect, and vice versa.because of the high school math knowledge vector operation, the mathematical formula:Formula One:two points A (x1,y1), B (x2,y2)Vector a=ab= (x2-x1,y2-y1);
Formula Two:Vector a= (Xa,ya), b= (XB,YB)                                  cosa=a*b/(|a|*|b|)the projection of vectors A to B = |a|*cosa=|a|* (a*b/(|a|*|b|) )=  (A.B)/|b|A*b=xa*xb+ya*yb;|b|=sqrt (XB*XB+YB*YB);projection =(A.B)/|b|=(xa*xb+ya*yb)/sqrt (XB*XB+YB*YB)Note: We need the projection we only take a positive numberThe projection size of the rectangle in a line = the sum of the absolute values of the projection of two adjacent edges on the line, such as the rectangle b1b2b3b4 in the x projection =| B3B1 on the x-axis projection |+| B1B2 on the x-axis projection |=+| B1B2 on the x-axis projection |+| B2B4 in X-axis projection |I do not add painting, painting more flowers, you should see also should understand that the x-axis on the chart to change the line a1a2 or A3A4 is the same effect, so we must not be confused by this, I just want to let everyone see the point
The principle is clear, the code is not a problem, you learn what language is used in what language, because I learn Java, then I use Java implementationHere is my source code, we just have to look at two rectangular collisions there can be
I this is to determine a rectangle with 4 vertices, the client needs to do so, in fact, I think a central point, a long, wide, rotating angle to determine should be a better rectangle, or four vertices, in case the wrong one, the spelling is not a rectangle that is not a problem.



Package game;/** * @author HJN * */public abstract class Abstractshape implements IShape {protected int x;protected int y; public abstractshape (int x, int y) {super (); this.x = X;this.y = y;} public int GetX () {return x;} public void SetX (int x) {this.x = x;} public int GetY () {return y;} public void sety (int y) {this.y = y;}}

Package game;/** * @author HJN * */public interface IShape {int GetX (), int GetY (); Boolean collision (IShape other); Boolean Contains (int px, int py), IShape copy (), void moveTo (int px, int py);}

/** * */package game;/** * Round * * @author HJN * */public class Circle extends Abstractshape {/** radius */private int Radiu    S;public Circle (int px, int py, int radius) {super (px, py); This.radius = radius;} /** * does not overlap with other images */@Overridepublic Boolean collision (IShape other) {if (other instanceof Circle) {Circle Othercirc Le = (Circle) other;return (This.radius + Othercircle.radius) * (This.radius + Othercircle.radius) >= ((This.x-otherc ircle.x) * (this.x-othercircle.x) + (THIS.Y-OTHERCIRCLE.Y) * (THIS.Y-OTHERCIRCLE.Y));} else if (other instanceof Rectangle) {return other.collision (this);} return false;}  /** * contains a point */@Overridepublic Boolean contains (int px, int py) {return This.radius * radius-((this.x-px) * (This.x- px) + (this.y-py) * (this.y-py)) >= 0;} public int Getradius () {return radius;} public void Setradius (int radius) {This.radius = radius;} @Overridepublic Circle Copy () {return new Circle (radius, radius, radius);} @Overridepublic void moveTo (int px, inT py) {this.x = Px;this.y = py;}} 


/** * */package game;/** * Rectangle * * @author HJN * */public class Rectangle extends Abstractshape {/** rectangle vertex */private int [] vertex;public Rectangle (int px, int py, int[][] vertex) {super (px, py); This.vertex = vertex;} /** * If there is overlap, the distance from the center to the rectangle 6 is less than the radius of the circle and the center is not in the rectangle then this rectangle overlaps the circle */@Overridepublic Boolean collision (IShape other) {try {if Instanceof circle) {Circle circle = (CIRCLE) Other;boolean fla = this.getlength (circle.x, Circle.y, vertex[0][0],vertex[0 ][1], vertex[1][0], vertex[1][1])-Circle.getradius () < 0;IF (FLA) {return true;} Boolean FLA2 = This.getlength (circle.x, Circle.y, vertex[0][0],vertex[0][1], vertex[2][0], vertex[2][1])- Circle.getradius () < 0;if (FLA2) {return true;} Boolean fla3 = This.getlength (circle.x, Circle.y, vertex[0][0],vertex[0][1], vertex[3][0], vertex[3][1])- Circle.getradius () < 0;if (FLA3) {return true;} Boolean fla4 = This.getlength (circle.x, Circle.y, vertex[1][0],vertex[1][1], vertex[2][0], vertex[2][1])- Circle.getradius () < 0;if (FLA4) {RETUrn true;} Boolean fla5 = This.getlength (circle.x, Circle.y, vertex[1][0],vertex[1][1], vertex[3][0], vertex[3][1])- Circle.getradius () < 0;if (FLA5) {return true;} Boolean fla6 = This.getlength (circle.x, Circle.y, vertex[2][0],vertex[2][1], vertex[3][0], vertex[3][1])- Circle.getradius () < 0;if (FLA6) {return true;} Boolean fla7 = This.contains (circle.x, Circle.y), if (FLA7) {return true;}} else if (other instanceof Rectangle) {Rectangle Otherrectangle = (Rectangle) Other;return This.collisionobb ( Otherrectangle);}} catch (Exception e) {//array subscript out of bounds e.printstacktrace (); return false;} return false;} /** * OBB Rectangle Collision Detection * @param rectangle Rectangle 2 * @return */private boolean collisionobb (Rectangle rectangle) {int[][] Vertex2=recta ngle.vertex;/* Rectangle 2 Adjacent two sides of the vector */int wx1=vertex2[0][0]-vertex2[1][0];int wy1=vertex2[0][1]-vertex2[1][1];int wx2= Vertex2[1][0]-vertex2[2][0];int wy2=vertex2[1][1]-vertex2[2][1];/* Two Rectangle center point connection Vector */int centerx= (vertex2[0][0]+ Vertex2[2][0])/2-(vertex[0][0]+vertex[2][0])/2;int centery= (verTex2[0][0]+vertex2[2][0])/2-(vertex[0][0]+vertex[2][0])/2;/* rectangle first edge vector */int x11=vertex[0][0]-vertex[1][0];int y11=vertex[0][1]-vertex[1][1];/* Rectangle One on the first side of the projection */double le1=math.sqrt (X11*X11+Y11*Y11);/* Rectangle 2 adjacent two edges on the first edge of the rectangle 1 projection, For example, projection211 represents a projection of the 1th edge of the 2nd rectangle on the 1th edge of the rectangle 1 */double projection2111=this.getprojection (wx1, Wy1, X11, Y11);d ouble Projection2211=this.getprojection (wx2, Wy2, X11, Y11);/* Projection of the center point connection vector */double centerprojection1=this.getprojection ( CenterX, CenterY, X11, Y11);/* Two rectangle projection and */double total=projection2111+projection2211+le1;/* If the center point vector projection is greater than half of the sum of the rectangle projection, there is certainly no collision */if (CENTERPROJECTION1&GT;TOTAL/2) {return false;} int X12=vertex[1][0]-vertex[2][0];int y12=vertex[1][1]-vertex[2][1];d ouble le2=math.sqrt (x12*x12+y12*y12);d ouble Projection2112=this.getprojection (wx1, Wy1, X12, Y12);d ouble projection2212=this.getprojection (wx2, Wy2, X12, Y12); Double Centerprojection2=this.getprojection (CenterX, CenterY, X12, Y12); if (Centerprojection2> (projection2112+ Projection2212+le2)/2) {return false;} /* In turn rectangle 1 is projected on two adjacent sides of Rectangle 2Half with the center point vector projection size contrast, do not write a comment */int wx11=vertex[0][0]-vertex[1][0];int wy11=vertex[0][1]-vertex[1][1];int wx12=vertex[1] [0]-vertex[2][0];int wy12=vertex[1][1]-vertex[2][1];int X21=vertex2[1][0]-vertex2[2][0];int y21=vertex2[1][1]- VERTEX2[2][1];d ouble le3=math.sqrt (x21*x21+y21*y21);d ouble projection1121=this.getprojection (wx11, Wy11, x21, Y21); Double Projection1221=this.getprojection (wx12, Wy12, x21, Y21);d ouble centerprojection3=this.getprojection (CenterX, CenterY, x21, Y21); if (centerprojection3> (PROJECTION1121+PROJECTION1221+LE3)/2) {return false;} int X22=vertex2[1][0]-vertex2[2][0];int y22=vertex2[1][1]-vertex2[2][1];d ouble le4=math.sqrt (X22*X22+Y22*Y22); Double Projection1122=this.getprojection (wx11, Wy11, x22, Y22);d ouble projection1222=this.getprojection (wx12, Wy12, x22, Y22);d ouble centerprojection4=this.getprojection (CenterX, CenterY, x22, Y22); if (Centerprojection4> ( PROJECTION1122+PROJECTION1222+LE4)/2) {return false;} return true;} /** * Vector 1 in vector 2 projection * @param x1 vector 1 x coordinate * @param y1 vectorThe y-coordinate of 1 * @param the x-coordinate of the X2 Vector 2 * @param the y-coordinate of y2 Vector 2 * @return The absolute value of the projection */private double getprojection (int x1,int y1,int x2,int y2) {Double t= (x1*x2+y1*y2)/(Math.sqrt (x1*x1+y1*y1) *math.sqrt (x2*x2+y2*y2));d ouble length=math.sqrt (x1*x1+y1*y1) *t; return Math.Abs (length);} /** * contains a point */@Overridepublic Boolean contains (int px, int py) {Double L = this.getlength (px, py, vertex[0][0], vertex[0 ][1],vertex[1][0], vertex[1][1]);d ouble l1 = this.getlength (px, py, vertex[1][0], vertex[1][1],vertex[2][0], vertex[2] [1]); Double L2 = this.getlength (px, py, vertex[2][0], vertex[2][1],vertex[3][0], vertex[3][1]);d ouble l3 = this.getlength (px, PY, vertex[3][0], vertex[3][1],vertex[0][0], vertex[0][1]);d ouble total = L1 + L2 + L3 + l;double width = this.getlength (v Ertex[0][0], vertex[0][1], vertex[1][0],vertex[1][1]);d ouble height = this.getlength (vertex[3][0], vertex[3][1], Vertex[0][0], vertex[0][1]); return total = = (width + height);} /* Distance between two points */private double getlength (int x1, int y1, int x2, int y2) {return MatH.sqrt ((x1-x2) * (X1-X2) + (y1-y2) * (Y1-y2));             /** * point to segment distance * * @param x * point x coordinate * @param y * point y coordinate * @param x1 * Segment Vertex 1x coordinates * @param y1 * Segment Vertex 1y coordinates * @param x2 * Segment Vertex 2x coordinate * @param y2 * segment vertex 2y coordinates * @return */private double Getlen gth (int x, int y, int x1, int y1, int x2, int y2) {Double cross = (x2-x1) * (x-x1) + (y2-y1) * (Y-Y1); if (Cross &L t;= 0) {return math.sqrt ((x-x1) * (x-x1) + (y-y1) * (y-y1));}  Double D2 = (x2-x1) * (x2-x1) + (y2-y1) * (y2-y1), if (cross >= D2) {return math.sqrt ((x-x2) * (x-x2) + (Y- y2) * (Y-y2));}  Double r = cross/d2;double px = x1 + (x2-x1) * r;double py = y1 + (y2-y1) * R;return math.sqrt ((x-px) * (X-PX) + (py-y) * (py-y));} Public int[][] Getvertex () {return vertex;} public void Setvertex (int[][] vertex) {This.vertex = vertex;} @Overridepublic Rectangle Copy () {return new Rectangle (x, y, vertex);} @Overridepublic void moveTo (int px, int py) {int VX = Px-this.x;int VY = py-this.y;int[][] Copyofvertex = new Int[this.vertex.length][2];for (int i = 0; i < This.vert Ex.length; i++) {Copyofvertex[i][0] = vx + this.vertex[i][0];copyofvertex[i][1] = vy + this.vertex[i][1];} this.x = Px;this.y = py;}}

Package Game;public class Test {//Based on two points can get the vector//according to a point can be obtained//based on two points get @org.junit.testpublic void Test () {Circle C1=new Circle (0, 0, 71); Circle C2=new Circle (0, 76, 2);/* Whether the circle contains a circle */system.out.println ("Circle contains Circle" +c1.collision (C2));/* 4 points of the rectangle */int[][] in=new int[4] [2];in[0][0]=0;in[0][1]=100;in[1][0]=100;in[1][1]=0;in[2][0]=200;in[2][1]=100;in[3][0]=100;in[3][1]=200; Rectangle rectangle1=new Rectangle (+, +, in);/* Whether the rectangle contains a circle */system.out.println ("The rectangle contains a circle:" + (Rectangle1.collision (c1 ));/* The circle contains the rectangle */system.out.println ("Circle contains rectangle:" + (C1.collision (rectangle1)));/* The rectangle contains the point */system.out.println ("Rectangle containing point:" + Rectangle1.contains (55, 49));/* 4 dots of rectangle */int[][] In2=new int[4][2];in2[0][0]=0;in2[0][1]=44;in2[1][0]=0;in2[1][1]=0 ; in2[2][0]=44;in2[2][1]=0;in2[3][0]=44;in2[3][1]=44; Rectangle rectangle2=new Rectangle (, in2), long Start=system.currenttimemillis (); Rectangle2.collision ( RECTANGLE1); for (int i=0;i<100000;i++) {//c1.collision (C2);//c1.collision (rectangle1); Rectangle2.collision ( RECTANGLE1);} Long End =system.currenttimemillIs (); System.out.println ((End-start)); System.out.println ("Rectangle contains rectangle:" +rectangle2.collision (Rectangle1));}}




Reference BlogHttp://blog.csdn.net/i_dovelemon/article/details/31420749http://www.cnblogs.com/iamzhanglei/archive/2012/06/07 /2539751.htmlhttp://www.cnblogs.com/iamzhanglei/archive/2012/06/07/2539751.html

OBB algorithm implementation of game collision (Java code Implementation)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.