flash on 2013-7-10

by mutantleg
♥0 | Line 172 | Modified 2013-07-10 23:05:32 | MIT License
play

ActionScript3 source code

/**
 * Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ykA8
 */

package {
    import flash.text.TextField;
    import flash.events.Event;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
   
        public function FlashTest() {
          
          var a:xCutter;
          
          var num:Number;
          
          num = 128;
          
          vecCutter[0].setPlane(-num, 0,0,  1, 0, 0);
          vecCutter[1].setPlane(0,-num,0,  0, 1, 0);  
          vecCutter[2].setPlane(num, 0,0,  -1, 0, 0);
          vecCutter[3].setPlane(0,num,0,  0, -1, 0);
          vecCutter[4].setPlane(0,0,-num,  0, 0, 1);
          vecCutter[5].setPlane(0,0,num,  0, 0, -1);
          
          deb = new TextField();
          deb.mouseEnabled = false;
          deb.width = 320;
          deb.height = 240;
          addChild(deb);
          
          
            stage.addEventListener(Event.ENTER_FRAME, onEnter);
        }//ctor
        
        public var ang:Number = 0;
        
        public var myTri:xTri = new xTri();
        
        public var deb:TextField;
        
        
        public function onEnter(e:Event):void
        {
            graphics.clear();
            
            graphics.lineStyle(2, 0);
            
            deb.text = "";
            
            ang += 0.03;
            
            /*
            myTri.a.setValue(-200,-200,0);
            myTri.b.setValue(200,0,0);
            myTri.c.setValue(0,200,0);
         */
         
              myTri.a.setValue(Math.cos(ang-1.57)*200,Math.sin(ang-1.57)*200,0);
             myTri.b.setValue(Math.cos(ang)*200,Math.sin(ang)*200,0);
             myTri.c.setValue(Math.cos(ang+1.57)*200,Math.sin(ang+1.57)*200,0);
          
          
            
            //renderTri(myTri);
            
            drawCut(myTri, 0);
            
        }//onenter
        
        
        
       public var vecCutter:Vector.<xCutter> =  Vector.<xCutter>([new xCutter(), new xCutter(), new xCutter(), new xCutter(), new xCutter(), new xCutter()]);

        public function drawCut(tri:xTri, d:int=0):void
        {
          var cut:xCutter;
          var num:int;
          
          if (d >= 6) { renderTri(tri); return; }
          
          cut = vecCutter[d];
          num = cut.cutTri(tri);
          if (num < 0) {  return; }
          if (num == 0) { drawCut(tri, d+1); return; }
          
          drawCut(cut.ret1, d+1);
          
          if (num > 1) { drawCut(cut.ret2, d+1);}
          
        }//drawtri
        
        public function renderTri(tri:xTri):void
        {
            //deb.appendText(" tri ");
            
            graphics.beginFill(0, 0.5);
            graphics.moveTo(tri.a.cx+200, tri.a.cy+200);
            graphics.lineTo(tri.b.cx+200, tri.b.cy+200);
            graphics.lineTo(tri.c.cx+200, tri.c.cy+200);
            graphics.lineTo(tri.a.cx+200, tri.a.cy+200);
            graphics.endFill();
            
        }//rendertri
                
                
        
    }//classend
}



internal class xVert
{
  public var cx:Number = 0;
  public var cy:Number = 0;
  public var cz:Number = 0;
  
  public function copyVert(b:xVert):void  {     cx = b.cx; cy = b.cy; cz = b.cz;  }
  
  public function setValue(vx:Number, vy:Number, vz:Number):void
  { cx = vx; cy = vy; cz = vz;}
  
}//xvert

internal class xTri
{
  public var a:xVert = new xVert();
  public var b:xVert = new xVert();
  public var c:xVert = new xVert();
  
}//xtri

internal class xCutter
{

public var ret1:xTri = new xTri();
public var ret2:xTri = new xTri();

public var num:int = 0;

public var cx:Number = 0;
public var cy:Number = 0;
public var cz:Number = 0;

public var cnx:Number = 0;
public var cny:Number = 0;
public var cnz:Number = 0;


public function setPlane(x_:Number, y_:Number, z_:Number, nx_:Number, ny_:Number, nz_:Number):void
{
    cx = x_;
    cy = y_;
    cz = z_;
    cnx = nx_;
    cny = ny_;
    cnz = nz_;
    
}//setplane

public function isFront(tri:xTri):int
{
    var ad:Number; var bd:Number; var cd:Number;
  
    ad = (tri.a.cx - cx) *cnx +  (tri.a.cy - cy) *cny +(tri.a.cz - cz) *cnz
    bd = (tri.b.cx - cx) *cnx +  (tri.b.cy - cy) *cny +(tri.b.cz - cz) *cnz  
    cd = (tri.c.cx - cx) *cnx +  (tri.c.cy - cy) *cny +(tri.c.cz - cz) *cnz
  
    if (ad > 0 && bd > 0 && cd > 0) { return 1; } //front of plane
    if (ad < 0 && bd < 0 && cd < 0) { return -1; } //behind plane
    return 0; //intersect    
}//isfront

public function cutTri(tri:xTri):int
{
  num = cutTriPlane(tri, cx, cy,cz, cnx, cny, cnz);
  return num;
}//cut


public static var tempOut:Vector.<xVert> = Vector.<xVert>([new xVert(), new xVert(), new xVert(), new xVert()]);

    public function cutTriPlane(tri:xTri,
    px:Number, py:Number, pz:Number,
    nx:Number, ny:Number, nz:Number):int
    {
      var vecOut:Vector.<xVert>;
      var it:int;
      var i:int;
      var ad:Number; var bd:Number; var cd:Number;
      var t:Number;
      var va:xVert; var vs:xVert;
      var da:Number; var ds:Number;
      var dw:xVert;
      
      vecOut = tempOut;
      
      
        ad = (tri.a.cx - px) *nx +  (tri.a.cy - py) *ny +(tri.a.cz - pz) *nz
        bd = (tri.b.cx - px) *nx +  (tri.b.cy - py) *ny +(tri.b.cz - pz) *nz
        cd = (tri.c.cx - px) *nx +  (tri.c.cy - py) *ny +(tri.c.cz - pz) *nz
      
        if (ad > 0 && bd > 0 && cd > 0) { return 0; } //front of plane
      
    
      it = 0;
    
      //todo -- unroll later (and by unroll i mean no loop really needed here)
      for (i = 0; i < 3; i++)
      {
        if (i == 0) 
        {
          va = tri.a;      vs = tri.c;      da = ad;      ds = cd;
        
        } else if (i == 1)
        {
          va = tri.b;      vs = tri.a;      da = bd;      ds = ad;
        
        } else 
        {
          va = tri.c;      vs = tri.b;      da = cd;      ds = bd;
        }
      
      
            if (da > 0 && ds > 0)
            {
              vecOut[it].copyVert(va);
              it += 1;
            }
            else if (da > 0 || ds > 0)
            {
              
                  t = da / (nx * (va.cx - vs.cx) + ny * (va.cy - vs.cy) +  nz * (va.cz - vs.cz) );
                  dw = vecOut[it];   
                          dw.cx = va.cx + (vs.cx - va.cx) * t;
                          dw.cy = va.cy + (vs.cy - va.cy) * t;
                          dw.cz = va.cz + (vs.cz - va.cz) * t;
                 
                       it += 1; 
                       
                  if (ds < 0)
                  {              
                    vecOut[it].copyVert(va);
                    it += 1;
                  }
            }//endif
            
      }//nexti
      
      if (it < 3) { return -1;}
      
      ret1.a.copyVert(vecOut[0]);
      ret1.b.copyVert(vecOut[1]);
      ret1.c.copyVert(vecOut[2]);
      
      if (it == 3) { return 1; }
      
      ret2.a.copyVert(vecOut[0]);
      ret2.b.copyVert(vecOut[2]);
      ret2.c.copyVert(vecOut[3]);
      
      
        return 2;
    }//cuttriplane

}//xcutter