Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Mar 13th, 2012  |  syntax: ActionScript 3  |  size: 5.88 KB  |  views: 40  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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. }
clone this paste RAW Paste Data