Guest User

Untitled

a guest
Mar 13th, 2012
155
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // File "SAT.as"
  2.  
  3. package  
  4. {
  5.     import Box2D.Common.Math.b2Vec2;
  6.     import flash.display.*;
  7.     import flash.geom.*;
  8.     import flash.events.*;
  9.     import flash.utils.Timer;
  10.    
  11.     /**
  12.      * SAT.as
  13.      * Created On:  12/03/2012 17:46
  14.      */
  15.    
  16.     [SWF(backgroundColor="0x000000", frameRate="60", width="800", height="600")]
  17.     public class SAT extends Sprite
  18.     {
  19.         private static var square:Vector.<b2Vec2>;
  20.         private static var canvas:Sprite;
  21.         private var A:Shape2D;
  22.         private var B:Shape2D;
  23.        
  24.         public function SAT()
  25.         {
  26.             // SPRITE TO DRAW SHAPES TO:
  27.             canvas = new Sprite();
  28.             // SHAPE OF A:
  29.             A = new Shape2D(Vector.<b2Vec2>([
  30.             new b2Vec2( -100, -100),
  31.             new b2Vec2( -100, 100),
  32.             new b2Vec2( 100, 100),
  33.             new b2Vec2( 100, -100)]), new b2Vec2(550, 300), 45);
  34.             // SHAPE OF B:
  35.             B = new Shape2D(Vector.<b2Vec2>([
  36.             new b2Vec2( -200, -50),
  37.             new b2Vec2( -200, 50),
  38.             new b2Vec2( 200, 50),
  39.             new b2Vec2( 200, -50)]), new b2Vec2(250, 300), 175);
  40.             // ADD CANVAS TO STAGE:
  41.             stage.addChild(canvas);
  42.             // DRAW A & B:
  43.             A.draw(canvas, false);
  44.             B.draw(canvas, false);
  45.             collides(A, B);
  46.            
  47.             /*
  48.             // TIMER THAT TRIGGERS FUNCTION 'ROTATE' EVERY 10MS:
  49.             var t:Timer = new Timer(10);
  50.             t.addEventListener(TimerEvent.TIMER, rotate);
  51.             t.start();
  52.             */
  53.         }
  54.         public function rotate(e:TimerEvent):void
  55.         {
  56.             // INCREMENT ANGLES:
  57.             A.angle++;
  58.             B.angle++;
  59.            
  60.             // CLEAR GRAPHICS:
  61.             canvas.graphics.clear();
  62.            
  63.             // FILL SHAPE IF IT'S CURRENTLY COLLIDING:
  64.             if (collides(A, B))
  65.             {
  66.                 A.draw(canvas, true);
  67.                 B.draw(canvas, true);
  68.             } else {
  69.                 A.draw(canvas, false);
  70.                 B.draw(canvas, false);
  71.             }
  72.         }
  73.         public function collides(A:Shape2D, B:Shape2D):Boolean
  74.         {
  75.             var test1:Number;   // numbers to use to test for overlap
  76.             var test2:Number;
  77.             var testNum:Number; // number to test if its the new max/min
  78.             var min1:Number;    // current smallest(shape 1)
  79.             var max1:Number;    // current largest(shape 1)
  80.             var min2:Number;    // current smallest(shape 2)
  81.             var max2:Number;    // current largest(shape 2)
  82.             var axis:b2Vec2;    // the normal axis for projection
  83.             var offset:Number;
  84.             var vectorOffset:b2Vec2;
  85.             var vectors1:Vector.<b2Vec2>;   // the points
  86.             var vectors2:Vector.<b2Vec2>;   // the points
  87.             vectors1 = A.getOBB().concat(); // these functions are in my polygon class, all they do is return a Vector.<b2Vec2> of the vertices of the polygon
  88.             vectors2 = B.getOBB().concat();
  89.            
  90.             /* SHOULDN'T NEED THIS AS BOTH VECTORS CONSIST OF 4 OBJECTS.
  91.              * ALSO B2VEC2 DOESN'T HAVE A TRUNCATE FUNCTION.
  92.              *
  93.             // add a little padding to make the test work correctly
  94.             if (vectors1.length == 2)
  95.             {
  96.                 var temp:b2Vec2 = new b2Vec2(-(vectors1[1].y - vectors1[0].y), vectors1[1].x - vectors1[0].x);
  97.                 temp.truncate(0.0000000001);
  98.                 vectors1.push(vectors1[1].add(temp));
  99.             }
  100.             if (vectors2.length == 2)
  101.             {
  102.                 temp = new b2Vec2(-(vectors2[1].y - vectors2[0].y), vectors2[1].x - vectors2[0].x);
  103.                 temp.truncate(0.0000000001);
  104.                 vectors2.push(vectors2[1].add(temp));
  105.             }
  106.             */
  107.            
  108.             // find vertical offset
  109.             vectorOffset = new b2Vec2(A.position.x - B.position.x, A.position.y - B.position.y);
  110.            
  111.             // loop to begin projection
  112.             for (var i:int = 0; i < vectors1.length; i++)
  113.             {
  114.                 // get the normal axis, and begin projection
  115.                 axis = findNormalAxis(vectors1, i);
  116.                 trace("AXIS:", axis.x, axis.y);
  117.                
  118.                 // project polygon1
  119.                 min1 = dotProduct(axis, vectors1[0]);
  120.                 max1 = min1;//set max and min equal
  121.                
  122.                 for (var j:int = 1; j < vectors1.length; j++)
  123.                 {
  124.                     testNum = dotProduct(axis, vectors1[j]);// project each point
  125.                     if (testNum < min1) min1 = testNum;     // test for new smallest
  126.                     if (testNum > max1) max1 = testNum;     // test for new largest
  127.                 }
  128.                
  129.                 trace("MIN1:", min1);
  130.                 trace("MAX1:", max1);
  131.                
  132.                 // project polygon2
  133.                 min2 = dotProduct(axis, vectors2[0]);
  134.                 max2 = min2;    // set 2's max and min
  135.                
  136.                 for (j = 1; j < vectors2.length; j++)
  137.                 {
  138.                     testNum = dotProduct(axis, vectors2[j]);// project the point
  139.                     if (testNum < min2) min2 = testNum;     // test for new min
  140.                     if (testNum > max2) max2 = testNum;     // test for new max
  141.                 }
  142.                
  143.                 trace("MIN2:", min2);
  144.                 trace("MAX2:", max2);
  145.                
  146.                 // apply the offset to each max/min(no need for each point, max and min are all that matter)
  147.                 offset = dotProduct(axis, vectorOffset);// calculate offset
  148.                 min1 += offset;                         // apply offset
  149.                 max1 += offset;                         // apply offset
  150.                
  151.                
  152.                 trace("MIN1OFFSET:", min1);
  153.                 trace("MAX1OFFSET:", max1);
  154.                
  155.                 // and test if they are touching
  156.                 test1 = min1 - max2;    // test min1 and max2
  157.                 test2 = min2 - max1;    // test min2 and max1
  158.                
  159.                 trace("TEST1:", test1);
  160.                 trace("TEST2:", test2);
  161.                 trace("TEST1 > 0 || TEST2 > 0:", test1 > 0 || test2 > 0);
  162.                
  163.                 if (test1 > 0 || test2 > 0)
  164.                 {   //if they are greater than 0, there is a gap
  165.                     trace("RETURN: FALSE");
  166.                     return false;//just quit
  167.                 }
  168.             }
  169.             //if you're here, there is a collision
  170.             var seperation:b2Vec2 = new b2Vec2(axis.x*((max2-min1)*-1), axis.y*((max2-min1)*-1)); //return the separation, apply it to a polygon to separate the two shapes.
  171.             return true;
  172.         }
  173.         private function dotProduct(vecA_:b2Vec2, vecB_:b2Vec2):Number
  174.         {
  175.             return (vecA_.x * vecB_.x + vecA_.y * vecB_.y);
  176.         }
  177.         private function findNormalAxis(verts:Vector.<b2Vec2>, index:int):b2Vec2
  178.         {
  179.             var vector1:b2Vec2 = verts[index];
  180.             var vector2:b2Vec2 = (index >= verts.length - 1) ? verts[0] : verts[index + 1];     //make sure you get a real vertex, not one that is outside the length of the vector.
  181.              
  182.             var normalAxis:b2Vec2 = new b2Vec2( -(vector2.y - vector1.y), vector2.x - vector1.x);//take the two vertices, make a line out of them, and find the normal of the line
  183.             normalAxis.Normalize(); //normalize the line(set its length to 1)
  184.             return normalAxis;
  185.         }
  186.     }
  187. }
RAW Paste Data