In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2012-12-4

Get Adobe Flash player
by mutantleg 04 Dec 2012
    Embed
/**
 * Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4xB4
 */

package {
    import flash.events.Event;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {

        public var myTri:Tri = new Tri();
        public var myRes:CutResultTri = new CutResultTri();

        public function FlashTest() {

            myTri.v0.setValue(60, 50, 0);
            myTri.v1.setValue(300, 60, 0);
            myTri.v2.setValue(140, 200, 0);
            
            
            stage.addEventListener(Event.ENTER_FRAME, onEnter);
        }//ctor
        
        public function onEnter(e:Event):void
        {
            graphics.clear();
            
            graphics.lineStyle(1, 0);
            
            graphics.moveTo(myTri.v0.cx, myTri.v0.cy);
            graphics.lineTo(myTri.v1.cx, myTri.v1.cy);
            graphics.lineTo(myTri.v2.cx, myTri.v2.cy);
            graphics.lineTo(myTri.v0.cx, myTri.v0.cy);
          
            var bCut:Boolean;
            var nx:Number;
            var ny:Number;
            var px:Number;
            var py:Number;
            
            nx = 1;
            ny = 0;
            
            px = mouseX;
            py = mouseY;

            bCut = cutTriByPlane(myTri, px, py, 0, nx, ny, 0, myRes);           
            
            graphics.drawCircle(px, py, 4);
            graphics.moveTo(px, py);
            graphics.lineTo(px+nx*10,py+ny*10);
            
           
 graphics.moveTo(px-ny*300,py+nx*300);
 graphics.lineTo(px+ny*300,py-nx*300);
            
            
            if (bCut == false) { return; }
            
           
           
var tri:Tri;

tri = myRes.t0;

graphics.beginFill(0xFF0000, 0.5);
 graphics.moveTo(tri.v0.cx, tri.v0.cy);
 graphics.lineTo(tri.v1.cx, tri.v1.cy);
 graphics.lineTo(tri.v2.cx, tri.v2.cy);
 graphics.lineTo(tri.v0.cx, tri.v0.cy);
graphics.endFill();

tri = myRes.t1;

graphics.beginFill(0x00FF00, 0.5);
 graphics.moveTo(tri.v0.cx, tri.v0.cy);
 graphics.lineTo(tri.v1.cx, tri.v1.cy);
 graphics.lineTo(tri.v2.cx, tri.v2.cy);
 graphics.lineTo(tri.v0.cx, tri.v0.cy);
graphics.endFill();

if (myRes.num > 2)
{
tri = myRes.t2;

graphics.beginFill(0x0000FF, 0.5);
 graphics.moveTo(tri.v0.cx, tri.v0.cy);
 graphics.lineTo(tri.v1.cx, tri.v1.cy);
 graphics.lineTo(tri.v2.cx, tri.v2.cy);
 graphics.lineTo(tri.v0.cx, tri.v0.cy);
 graphics.endFill();
}            
            
        }//onenter
        
        
        
        public function flipTri(t:Tri):void
        {
            var tmp:Vert;
            tmp = t.v1;
            t.v1 = t.v2;
            t.v2 = tmp;
        }//fliptri
        
        //arrays used by the function, so we dont make new objects everytime we call it
        public var vecUp:Array = [new Vert(), new Vert(), new Vert(), new Vert()];
        public var vecDown:Array = [new Vert(), new Vert(), new Vert(), new Vert()];
        
        public function cutTriByPlane(tri:Tri, //triangle to cut
        px:Number, py:Number, pz:Number, //plane position
        nx:Number, ny:Number, nz:Number, //plane normal
        ret:CutResultTri):Boolean
        {
          if (ret == null) { return false; }  
          
          /*
          
              ok, so what's happenning here is that:
              - first we determine if the triangle can be cut at all 
              or if there is no point to it:
              (we cannot cut it, if the triangle is exactly on the plane, 
              or more than one vertex is on the plane, 
              or if all the vertices are on one side of the plane)
              
              - then we check that which edges are cut by the plane
              - we generate new vertices where the plane cuts an edge
              - and we build triangles based on these new vertices 
              (we got an easy job because there will be at most 4 vertices on either side of the plane)
              (also we got 2 cases: either we need to make two new triangles, that is if a vertex is on the plane,
              or three new if the plane cuts two edges)
              - for the newly generated triangles we check if their normal is roughly the
              same as the cut triangle's normal, if not we flip it
              
              and thats it, then the hard and messy part is somehow returning
              our newly generated triangles
              (of course in flash the easiest way would be to return them in an array and call it a day) 
              
          
          */
          
          var v0:Vert;
          var v1:Vert;
          var v2:Vert;
          var itu:int;
          var itd:int;
          var dist0:Number;
          var dist1:Number;
          var dist2:Number;
          var nump:int;
          var numneg:int;
          var ab:int; //01
          var ac:int; //02
          var bc:int; //12
          var abd:Number;
          var acd:Number;
          var bcd:Number;
          var t:Number;
          var dot:Number;
          
          itu = 0;
          itd = 0;
          nump = 0; 
          numneg = 0; 
          
          v0 = tri.v0;
          v1 = tri.v1;
          v2 = tri.v2;
          
          //distance of the triangle's points to the plane
           dist0 =  (v0.cx - px)*nx + (v0.cy - py)*ny + (v0.cz - pz)*nz;
           dist1 =  (v1.cx - px)*nx + (v1.cy - py)*ny + (v1.cz - pz)*nz;
           dist2 =  (v2.cx - px)*nx + (v2.cy - py)*ny + (v2.cz - pz)*nz;
          
           if (dist0 == 0) { nump += 1; }
           if (dist1 == 0) { nump += 1; }
           if (dist2 == 0) { nump += 1; }
          
          //an edge or the whole triangle is on the plane: don't cut
           if (nump > 1) { return false; }
            
           if (dist0 < 0) { numneg += 1; }  
           if (dist1 < 0) { numneg += 1; }  
           if (dist2 < 0) { numneg += 1; }  
           
          //if all points are on one side of the plane: nothing to cut
           if (numneg == 3 || numneg == 0) { return false; }
         
          //edges length
           abd = Math.abs(dist0) + Math.abs(dist1);
           acd = Math.abs(dist0) + Math.abs(dist2);
           bcd = Math.abs(dist1) + Math.abs(dist2);
         
          //check which edges the plane has cut
           ab = ((dist0 < 0 && dist1 > 0) || (dist0 > 0 && dist1 < 0 ) ) ? 1 : 0;
           ac = ((dist0 < 0 && dist2 > 0) || (dist0 > 0 && dist2 < 0 ) ) ? 1 : 0;
           bc = ((dist1 < 0 && dist2 > 0) || (dist1 > 0 && dist2 < 0 ) ) ? 1 : 0;
          
         //put in already existing vertices to the resulting tris list
         //based on their distance to the plane
        // (i guess you could put together some ifs and make it more optimised
        // but i want it to look clean, so its easier to see what is happening here)
        
         var dv:Vert;
         
         if (dist0 > 0) 
         {
             dv = vecUp[itu];
             dv.copyVert(v0);
             itu += 1;
         }//endif
         
         if (dist1 > 0) 
         {
             dv = vecUp[itu];
             dv.copyVert(v1);
             itu += 1;
         }//endif
         
         if (dist2 > 0) 
         {
             dv = vecUp[itu];
             dv.copyVert(v2);
             itu += 1;
         }//endif
         
         if (dist0 < 0) 
         {
             dv = vecDown[itd];
             dv.copyVert(v0);
             itd += 1;
         }//endif
         
         if (dist1 < 0) 
         {
             dv = vecDown[itd];
             dv.copyVert(v1);
             itd += 1;
         }//endif
         
         if (dist2 < 0) 
         {
             dv = vecDown[itd];
             dv.copyVert(v2);
             itd += 1;
         }//endif
         
         //special case: vertex is on the plane
         if (dist0 == 0) 
         {
             dv = vecUp[itu];
             dv.copyVert(v0);
             itu += 1;
             dv = vecDown[itd];
             dv.copyVert(v0);
             itd += 1;
         }//endif
         
         if (dist1 == 0) 
         {
             dv = vecUp[itu];
             dv.copyVert(v1);
             itu += 1;
             dv = vecDown[itd];
             dv.copyVert(v1);
             itd += 1;
         }//endif
         
         if (dist2 == 0) 
         {
             dv = vecUp[itu];
             dv.copyVert(v2);
             itu += 1;
             dv = vecDown[itd];
             dv.copyVert(v2);
             itd += 1;
         }//endif
         
         
         //generate new vertices at where the plane cuts the edge
         
         if (ab > 0)
         {
             t = Math.abs(dist0) / abd;
             
             dv = vecUp[itu];
              dv.cx = v0.cx + (v1.cx - v0.cx) * t;
              dv.cy = v0.cy + (v1.cy - v0.cy) * t;
              dv.cz = v0.cz + (v1.cz - v0.cz) * t;
             itu += 1;
             
             dv = vecDown[itd];
              dv.cx = v0.cx + (v1.cx - v0.cx) * t;
              dv.cy = v0.cy + (v1.cy - v0.cy) * t;
              dv.cz = v0.cz + (v1.cz - v0.cz) * t;
             itd += 1;
         }//endif
         
         if (ac > 0)
         {
             t = Math.abs(dist0) / acd;
             
             dv = vecUp[itu];
              dv.cx = v0.cx + (v2.cx - v0.cx) * t;
              dv.cy = v0.cy + (v2.cy - v0.cy) * t;
              dv.cz = v0.cz + (v2.cz - v0.cz) * t;
             itu += 1;
             
             dv = vecDown[itd];
              dv.cx = v0.cx + (v2.cx - v0.cx) * t;
              dv.cy = v0.cy + (v2.cy - v0.cy) * t;
              dv.cz = v0.cz + (v2.cz - v0.cz) * t;
             itd += 1;
         }//endif
         
         if (bc > 0)
         {
             t = Math.abs(dist1) / bcd;
             
             dv = vecUp[itu];
              dv.cx = v1.cx + (v2.cx - v1.cx) * t;
              dv.cy = v1.cy + (v2.cy - v1.cy) * t;
              dv.cz = v1.cz + (v2.cz - v1.cz) * t;
             itu += 1;
             
             dv = vecDown[itd];
              dv.cx = v1.cx + (v2.cx - v1.cx) * t;
              dv.cy = v1.cy + (v2.cy - v1.cy) * t;
              dv.cz = v1.cz + (v2.cz - v1.cz) * t;
             itd += 1;
         }//endif
         
         
         
         if (nump == 1) //one vertex was on the plane, we made 2 triangles
         {
             ret.num = 2;
             ret.t0.v0.copyVert( vecUp[0] ); 
             ret.t0.v1.copyVert( vecUp[1] ); 
             ret.t0.v2.copyVert( vecUp[2] );
             
             ret.t1.v0.copyVert( vecDown[0] ); 
             ret.t1.v1.copyVert( vecDown[1] ); 
             ret.t1.v2.copyVert( vecDown[2] );
              
         }
         else 
         if (itu == 3) //triangle cut 2 edges, make 3 triangles
         {
             ret.num = 3;
             
             ret.t0.v0.copyVert( vecUp[0] ); 
             ret.t0.v1.copyVert( vecUp[1] ); 
             ret.t0.v2.copyVert( vecUp[2] );
             
             ret.t1.v0.copyVert( vecDown[0] ); 
             ret.t1.v1.copyVert( vecDown[1] ); 
             ret.t1.v2.copyVert( vecDown[2] );
      
             ret.t2.v0.copyVert( vecDown[1] ); 
             ret.t2.v1.copyVert( vecDown[2] ); 
             ret.t2.v2.copyVert( vecDown[3] );       
         }
         else //two triangles were on the other side of the plane
         {
             ret.num = 3;
             
             ret.t0.v0.copyVert( vecDown[0] ); 
             ret.t0.v1.copyVert( vecDown[1] ); 
             ret.t0.v2.copyVert( vecDown[2] );
             
             ret.t1.v0.copyVert( vecUp[0] ); 
             ret.t1.v1.copyVert( vecUp[1] ); 
             ret.t1.v2.copyVert( vecUp[2] );
      
             ret.t2.v0.copyVert( vecUp[1] ); 
             ret.t2.v1.copyVert( vecUp[2] ); 
             ret.t2.v2.copyVert( vecUp[3] );    
             
         }//endif
         
         tri.calcNormal();
      
             ret.t0.calcNormal();
             dot = (tri.norm.cx * ret.t0.norm.cx) +(tri.norm.cy * ret.t0.norm.cy) + (tri.norm.cz * ret.t0.norm.cz);
             if (dot < 0) { flipTri(ret.t0); }
         
             ret.t1.calcNormal();
             dot = (tri.norm.cx * ret.t1.norm.cx) +(tri.norm.cy * ret.t1.norm.cy) + (tri.norm.cz * ret.t1.norm.cz);
             if (dot < 0) { flipTri(ret.t1); }

         if (ret.num > 2)
         {
             ret.t2.calcNormal(); 
             dot = (tri.norm.cx * ret.t2.norm.cx) +(tri.norm.cy * ret.t2.norm.cy) + (tri.norm.cz * ret.t2.norm.cz);
             if (dot < 0) { flipTri(ret.t2); }

         }//endif
         
         return true;   
        }//cuttriplane 
        
    }//classend
}//package

internal class Vert
{
    public var cx:Number = 0;
    public var cy:Number = 0;
    public var cz:Number = 0;
    
    public function setValue(x:Number, y:Number, z:Number):void
    {
      cx = x;
      cy = y;
      cz = z;   
    }//setvalue
    
    public function copyVert(v:Vert):void
    {
        cx = v.cx;
        cy = v.cy;
        cz = v.cz;
    }//copyvert
    
};//Vert

internal class Tri
{
    public var v0:Vert = new Vert();
    public var v1:Vert = new Vert();
    public var v2:Vert = new Vert();
    public var norm:Vert = new Vert();
    
    public function calcNormal():void
    {
        var ax:Number;
        var ay:Number;
        var az:Number;
        var bx:Number;
        var by:Number;
        var bz:Number;
        var mag:Number;
        
        ax = v0.cx - v1.cx;
        ay = v0.cy - v1.cy;
        az = v0.cz - v1.cz;
        bx = v0.cx - v2.cx;
        by = v0.cy - v2.cy;
        bz = v0.cz - v2.cz;
        
        //cross product
        norm.cx = (ay * bz) - (az * by);
        norm.cy = (az * bx) - (ax * bz);
        norm.cz = (ax * by) - (ay * bx);
        
        mag = Math.sqrt( (norm.cx*norm.cx) + (norm.cy*norm.cy) + (norm.cz*norm.cz) );
        if (mag == 0) { return; }
        
        norm.cx /= mag;
        norm.cy /= mag;
        norm.cz /= mag;
        
    }//calcnormal
    
};//Tri

internal class CutResultTri
{
    public var num:int = 0;
    public var t0:Tri = new Tri();
    public var t1:Tri = new Tri();
    public var t2:Tri = new Tri();
};//triresult