flash on 2013-6-28

by mutantleg
Followup to: http://wonderfl.net/c/jr9W
(and http://wonderfl.net/c/4xB4)

still trying to get my buggy triangle cutting function in shape
♥0 | Line 287 | Modified 2013-07-01 03:36:35 | 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/a8vY
 */

package {
    import flash.text.TextField;
    import flash.ui.Keyboard;
    import flash.events.KeyboardEvent;
    import flash.events.Event;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        public function FlashTest() {
            
            
            myFace = new xFace();
            myFace.a.setValue(20,20,0);
            //myFace.a.setValue(400,400,0);
            myFace.b.setValue(20,400,0);
            myFace.c.setValue(400,20,0);
            /*
            myFace.a.setValue(200,400,0);
            myFace.b.setValue(20,400,0);
            myFace.c.setValue(400,20,0);
            */
          
          deb = new TextField();
          deb.mouseEnabled = false;
          deb.width = 320;
          deb.height = 240;
          addChild(deb);
          
          xCutter.deb = deb;
          
            
            stage.addEventListener(KeyboardEvent.KEY_DOWN, kdown);
            stage.addEventListener(KeyboardEvent.KEY_UP, kup);
            stage.addEventListener(Event.ENTER_FRAME, onEnter);
        }//ctor
        
        public var vecKey:Vector.<Boolean> = new Vector.<Boolean>(512, false);
        
        public function kdown(e:KeyboardEvent):void { if (e.keyCode >511){ return;} vecKey[e.keyCode]=true;}
        public function kup(e:KeyboardEvent):void { if (e.keyCode>511) { return;} vecKey[e.keyCode] =false;}        
        
        public var deb:TextField;
        
        public var cx:Number = 300;
        public var cy:Number = 300;
        public var ang:Number  = 0;
        
        public var myFace:xFace = new xFace();
        
        /*
        public var ret1:xFace = new xFace();
        public var ret2:xFace = new xFace();
        
        public var ret3:xFace = new xFace();
        public var ret4:xFace = new xFace();
        
        public var ret5:xFace = new xFace();
        public var ret6:xFace = new xFace();
 
        public var ret7:xFace = new xFace();
        public var ret8:xFace = new xFace();
 */
 
         public var cut1:xCutter = new xCutter();
         public var cut2:xCutter = new xCutter();
         public var cut3:xCutter = new xCutter();
         
 
        
        public function onEnter(e:Event):void
        {
                 graphics.clear();
            graphics.lineStyle(2, 0);
            
            graphics.drawCircle(cx, cy, 8);
           
            var dx:Number;
            var dy:Number;
          
          
           if (vecKey[Keyboard.UP]) { cy -= 4; }
           if (vecKey[Keyboard.DOWN]) { cy += 4; }
           if (vecKey[Keyboard.LEFT]) { cx -= 4; }
           if (vecKey[Keyboard.RIGHT]) { cx += 4; }
           
          
           
            dx = stage.mouseX-cx;
            dy = stage.mouseY-cy;
           
            ang = Math.atan2(dy, dx);
            
            
            
            graphics.moveTo(cx, cy);
            graphics.lineTo(cx+Math.cos(ang)*8,cy+ Math.sin(ang)*8);
          
          var nx:Number;
          var ny:Number;
          
          nx = Math.cos(ang-0.7);
          ny = Math.sin(ang-0.7);
       
            
            graphics.moveTo(cx,cy);
            graphics.lineTo(cx+nx*256,cy+ny*256);
            
            graphics.moveTo(cx+nx*128,cy+ny*128);
            graphics.lineTo(cx+(nx*128)-ny*8,cy+(ny*128)+nx*8 );
            
            
          nx = Math.cos(ang+0.7);
          ny = Math.sin(ang+0.7);
          
            graphics.moveTo(cx,cy);
            graphics.lineTo(cx+nx*256,cy+ny*256);
          
            graphics.moveTo(cx+nx*128,cy+ny*128);
            graphics.lineTo(cx+(nx*128)+ny*8,cy+(ny*128)-nx*8 );
            
            
          nx = Math.cos(ang);
          ny = Math.sin(ang);
        
            graphics.moveTo(cx+nx-ny*64,cy+ny+nx*64 );
            graphics.lineTo(cx+nx+ny*64,cy+ny-nx*64 );
        
            
           
            var num1:int;
            var num2:int;
            var num3:int;
            var num3b:int;
            
            var fc:xFace;
            var fc2:xFace;
            var fc3:xFace;
            
            drawTri(myFace);
            
            //i keep screwing up the cutting function but not sure where
            
       //edit //2013/6/30
       //ok now i think i figured out
       //or at least it seem to work now ok
       
            
            
            cut1.setPlane(cx,cy, 0, Math.cos(ang), Math.sin(ang), 0);
            cut2.setPlane(cx,cy, 0, -Math.sin(ang-0.7), Math.cos(ang-0.7), 0);
            cut3.setPlane(cx,cy, 0, Math.sin(ang+0.7), -Math.cos(ang+0.7), 0);
            
            
            num1 = cut1.cutFace(myFace);
            
            if (num1 == 0) { fc = myFace;} else { fc = cut1.ret1; }
            
                graphics.lineStyle(4,0xFF0000);
                drawTri(fc);
        
               
                if (num1 > 1) {  graphics.lineStyle(3,0x880000);
                   drawTri(cut1.ret2);}
            /*   
                graphics.lineStyle(2,0);
            
                num2 = cut2.cutFace(fc);
                if (num2 == 0) { fc2 = fc;} else { fc2 = cut2.ret1; }
                
                graphics.lineStyle(4,0x00FF00);
                drawTri(fc2);
                
                graphics.lineStyle(2,0);
                
                if (num2>1) { fillTri(cut2.ret2, 0x808080,0.5) };
                
                    num3 = cut3.cutFace(fc2);
                    if (num3 == 0) { fc3 = fc2;} else { fc3 = cut3.ret1; }
                    
                    
                    
                     fillTri(fc3, 0xFF,0.5);
                     if (num3 > 1) { fillTri(cut3.ret2, 0xF0F0, 0.5); }
 
            
            
                   if (num2 > 1)
                   {
                     fc2 = cut2.ret2;
                     
                     drawTri(fc2);
                     
                     num3 = cut3.cutFace(fc2);
                     if (num3 == 0) { fc3 = fc2;} else { fc3 = cut3.ret1; }
                  
                     fillTri(fc3,0xFF0000, 0.5);
                    // if (num3 > 1) { fillTri(cut3.ret2, 0xFFF000, 0.5); }
                     
                   }
             */      
                   
            /*
            
            
          nx = Math.cos(ang);
          ny = Math.sin(ang);
            
            num1 = cutTri2(myFace, cx, cy, 0,  nx, ny, 0, ret1, ret2);
 
             if (num1 < 0) { return; }
             if (num1 == 0) { ret1.copyFace(myFace); }
             
             graphics.lineStyle(2, 0xFF0000);
             drawTri(ret1);
             if (num1>1) { drawTri(ret2); }
 
 
          nx = -Math.sin(ang-0.7);
          ny = Math.cos(ang-0.7);
       
             
             num2 = cutTri2(ret1, cx,cy,0, nx, ny, 0, ret3, ret4);
             
             if (num2 < 0) { return; }
             if (num2 == 0) { ret3.copyFace(ret1); }
             graphics.lineStyle(2, 0x00FF00);
              
              drawTri(ret3);
              if (num2>1) {drawTri(ret4);}

          nx = Math.sin(ang+0.7);
          ny = -Math.cos(ang+0.7);
              
              num3 = cutTri2(ret3, cx, cy, 0, nx, ny, 0, ret5, ret6);
             graphics.lineStyle(2, 0x0000FF);
               
               if (num3 < 0) { return; }
               if (num3 == 0) { ret5.copyFace(ret3); }
               
               drawTri(ret5);
               if (num3 >1) { drawTri(ret6);}
              
         */
            
        }//onenter
        
        
        public function fillTri(f:xFace, c:uint, a:Number=1.0):void
        {
            
            graphics.beginFill(c, a);
             graphics.moveTo(f.a.cx, f.a.cy);
             graphics.lineTo(f.b.cx, f.b.cy);
             graphics.lineTo(f.c.cx, f.c.cy);
             graphics.lineTo(f.a.cx, f.a.cy);
            graphics.endFill();
            
        }//filltri
        
        
        
        public function drawTri(f:xFace):void
        {
            graphics.moveTo(f.a.cx, f.a.cy);
            graphics.lineTo(f.b.cx, f.b.cy);
            graphics.lineTo(f.c.cx, f.c.cy);
            graphics.lineTo(f.a.cx, f.a.cy);
            
            
            graphics.drawCircle(f.a.cx, f.a.cy, 4);
            graphics.drawCircle(f.b.cx, f.b.cy, 7);
            graphics.drawCircle(f.c.cx, f.c.cy, 10);
            
        }//drawtri
        
        
        
        
        
        
        
        
        
     

        
        
    }//classend
}
import flash.text.TextField;

internal class xCutter
{
    public static var deb:TextField;
    
    public var ret1:xFace = new xFace();
    public var ret2:xFace = new xFace();
    
    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 xCutter():void
    {}//ctor
    
    public function setPlane( px:Number, py:Number, pz:Number,
            nx:Number, ny:Number, nz:Number):void
        {
            cx = px; cy = py; cz = pz;
            cnx = nx; cny =ny; cnz = nz;
            
            }//setplane
    
    public function cutFace(f:xFace):int
    {
        num = cutTri2(f, cx,cy,cz, cnx,cny,cnz, ret1, ret2);
        return num;
    }//cutface
    
        
        
        public var vecOut:Vector.<xVert> = Vector.<xVert>([new xVert(), new xVert(), new xVert(), new xVert()]);
        
        //cut triangle by plane
        //copies new tris into reta and retb
        //returns the number of tris created
        //note -- only returns the triangles on the front
        public function cutTri2(tri:xFace,
            px:Number, py:Number, pz:Number, //plane position
            nx:Number, ny:Number, nz:Number, //plane normal
            reta:xFace, retb:xFace):int
        {
            
            var it:int;
            var t:Number;
            var va:xVert;
            var vs:xVert;
            var dv:xVert;
            var da:Number;
            var ds:Number;
            
            var ccw:Number;
            
            var ad:Number;
            var bd:Number;
            var cd:Number;
            
            
               //todo -- optimisation
            //distance only need to be calculated ONCE per vertex
            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; }
            
            it = 0;
            
            
         
            
            
            
            //copy paste iminent
            
            
            vs = tri.a;
            va = tri.b;
            
            da =  (va.cx - px)*nx + (va.cy - py)*ny + (va.cz - pz)*nz;
            ds =  (vs.cx - px) * nx + (vs.cy - py) * ny + (vs.cz - pz) * nz;
            
            
            if (da > 0)
            {
                
                    vecOut[it].copyVert(va);
                    it += 1;
                
                if (ds <= 0)
                {
                    
                 t = da / (nx * (va.cx - vs.cx) + ny * (va.cy - vs.cy) +  nz * (va.cz - vs.cz) );
                 
                    dv = vecOut[it];
                      dv.cx = va.cx + (vs.cx - va.cx) * t;
                      dv.cy = va.cy + (vs.cy - va.cy) * t;
                    dv.cz = va.cz + (vs.cz - va.cz) * t;
             
                it += 1; 
       
                }//endif2
                
            }
            else if (ds > 0)
            {
                    t = da / (nx * (va.cx - vs.cx) + ny * (va.cy - vs.cy) +  nz * (va.cz - vs.cz) );
                    dv = vecOut[it];
                      dv.cx = va.cx + (vs.cx - va.cx) * t;
                      dv.cy = va.cy + (vs.cy - va.cy) * t;
                      dv.cz = va.cz + (vs.cz - va.cz) * t;

                it += 1; 

            }//endif2
            
            
            
            
            
               va = tri.a;
            vs = tri.c;
        
         
            da =  (va.cx - px)*nx + (va.cy - py)*ny + (va.cz - pz)*nz;
            ds =  (vs.cx - px)*nx + (vs.cy - py)*ny + (vs.cz - pz)*nz;
            
            if (da > 0)
            {
                
                    vecOut[it].copyVert(va);
                    it += 1;
                  
                if (ds <= 0)
                {
                    
                    t = da / (nx * (va.cx - vs.cx) + ny * (va.cy - vs.cy) +  nz * (va.cz - vs.cz) );
                 
                    dv = vecOut[it];
                      dv.cx = va.cx + (vs.cx - va.cx) * t;
                      dv.cy = va.cy + (vs.cy - va.cy) * t;
                      dv.cz = va.cz + (vs.cz - va.cz) * t;
          
                    it += 1; 
                    
               
                }//endif2
                
            }
            else if (ds > 0)
            {
                
                    t = da / (nx * (va.cx - vs.cx) + ny * (va.cy - vs.cy) +  nz * (va.cz - vs.cz) );
                    dv = vecOut[it];
                      dv.cx = va.cx + (vs.cx - va.cx) * t;
                      dv.cy = va.cy + (vs.cy - va.cy) * t;
                      dv.cz = va.cz + (vs.cz - va.cz) * t;
 
                    it += 1; 
  
            }//endif2
            
            
            
            
            
            
            
            
            vs = tri.b;
            va = tri.c;
                        
            da =  (va.cx - px)*nx + (va.cy - py)*ny + (va.cz - pz)*nz;
            ds =  (vs.cx - px) * nx + (vs.cy - py) * ny + (vs.cz - pz) * nz;
            
            if (da > 0)
            {
            
                    vecOut[it].copyVert(va);
                    it += 1;

                
                if (ds <= 0)
                {
                    
                 t = da / (nx * (va.cx - vs.cx) + ny * (va.cy - vs.cy) +  nz * (va.cz - vs.cz) );
                 
                    dv = vecOut[it];
                      dv.cx = va.cx + (vs.cx - va.cx) * t;
                      dv.cy = va.cy + (vs.cy - va.cy) * t;
                      dv.cz = va.cz + (vs.cz - va.cz) * t;
                    it += 1; 
                    
                }//endif2
                
            }
            else if (ds > 0)
            {
                    t = da / (nx * (va.cx - vs.cx) + ny * (va.cy - vs.cy) +  nz * (va.cz - vs.cz) );
                    dv = vecOut[it];
                      dv.cx = va.cx + (vs.cx - va.cx) * t;
                      dv.cy = va.cy + (vs.cy - va.cy) * t;
                      dv.cz = va.cz + (vs.cz - va.cz) * t;
  
                    it += 1; 

            }//endif2
            
            
            if (it < 3) { return -1; }
            
                reta.a.copyVert(vecOut[0]);
                reta.b.copyVert(vecOut[1]);
                reta.c.copyVert(vecOut[2]);
            
            if (it == 3) { return 1; }    
            
            /*
            ccw = (tri.b.cx - tri.a.cx)*(tri.c.cy - tri.a.cy) 
            - (tri.b.cy - tri.a.cy)*(tri.c.cx - tri.a.cx);
            */
            ccw = getCcw(tri.a, tri.b, tri.c);
            
            deb.text = "ccw " + ccw;
            
            var ccw2:Number;
            var ccw3:Number;
            
            ccw2 = getCcw(vecOut[1], vecOut[2], vecOut[3]);
            
            deb.appendText( "\n ccw2 " + ccw2);
                                    
            if ((ccw < 0 && ccw2 <0) || (ccw > 0 && ccw2 >0)  )            
            { 
                retb.a.copyVert(vecOut[1]);
                retb.b.copyVert(vecOut[2]);
                retb.c.copyVert(vecOut[3]);

            }
            else
            { 
                retb.a.copyVert(vecOut[2]);
                retb.b.copyVert(vecOut[0]);
                retb.c.copyVert(vecOut[3]);
 
             }
                            
            return 2;
        }//cuttri2
        
        
        //http://en.wikipedia.org/wiki/Graham_scan#Pseudocode
        public function getCcw(p1:xVert, p2:xVert, p3:xVert):Number
       {
             return (p2.cx - p1.cx)*(p3.cy - p1.cy) - (p2.cy - p1.cy)*(p3.cx - p1.cx);
       }//gettccw
    
}//xcutter






internal class xFace
{
    
    public var a:xVert = new xVert();
    public var b:xVert = new xVert();
    public var c:xVert = new xVert();
    
    public function copyFace(vf:xFace):void
    {
        a.copyVert(vf.a);
        b.copyVert(vf.b);
        c.copyVert(vf.c);
    }
    
 //   public function isSame(a:xFace):void
 //   {}
    

}//xface

internal class xVert
{
    public var cx:Number = 0;
    public var cy:Number = 0;
    public var cz:Number = 0;
    
    
    public function copyVert(va:xVert):void
    {        cx = va.cx;        cy = va.cy;        cz = va.cz;   }
    
    public function setValue(x:Number, y:Number, z:Number):void
    { cx = x; cy = y; cz = z; }

    
}//xvert