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

ff: Reflection

Bug fixed.
Get Adobe Flash player
by imo_ 27 Feb 2015
  • Forked from phi16's Reflection
  • Diff: 10
  • Related works: 4
  • Talk

    phi16 at 02 Mar 2015 13:14
    全反射として計算せざるを得ないのはわかるのですが、どうにも非連続で気持ち悪いと思ってしまうのです。 接点で反射率が増加してきて臨界角で1.0になる(全反射状態として計算しなくとも)のが理想かとおもっています。 近似式なのが悪いのかとも思いましたが臨界角で急に1.0になるなんてアレはないしどうにもよくわからんのです
    Embed
/**
 * Copyright imo_ ( http://wonderfl.net/user/imo_ )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/aSzh
 */

// forked from phi16's Reflection
package {

    import flash.display.Sprite;

    import flash.events.Event;

    public class Fresnel extends Sprite {

        public var bg:Sprite=new Sprite();

        public var spr:Sprite=new Sprite();

        public var IoR:Number=2.0;

        public function Fresnel() {

            addChild(bg);

            addChild(spr);

            bg.graphics.beginFill(0);

            bg.graphics.drawRect(0,0,465,465);

            bg.graphics.endFill();

            bg.graphics.lineStyle(2,0xffffff);

            bg.graphics.drawCircle(465/2.0,465/2.0,100);

            spr.x=465/2.0;

            spr.y=465/2.0;

            addEventListener(Event.ENTER_FRAME,step);

        }

        public function step(e:Event):void{

            spr.graphics.clear();

            rayTrace(mouseX-465/2.0,mouseY-465/2.0,0,-1,1);

        }

        public function rayTrace(a:Number,b:Number,c:Number,d:Number,alpha:Number):void{

            if(alpha<0.01)return;

            var lei:Number=Math.sqrt(c*c+d*d);

            c/=lei,d/=lei;

            a+=0.1*c;

            b+=0.1*d;

            spr.graphics.lineStyle(4,0xffffff,alpha);

            spr.graphics.moveTo(a,b);

            var f:Boolean=false;

            var D:Number,t:Number,p:Number,q:Number,le:Number,nx:Number,ny:Number,dp:Number,rx:Number,ry:Number,k:Number,f0:Number,fth:Number;

            D=-a*a*d*d+2*a*b*c*d-b*b*c*c+10000;

            if(a*a+b*b<10000){

                if(D>0){

                    t=Math.sqrt(D)-a*c-b*d;

                    if(t>0){

                        p=a+c*t,q=b+d*t;

                        spr.graphics.lineTo(p,q);

                        le=Math.sqrt(p*p+q*q);

                        nx=-p/le,ny=-q/le;

                        dp=c*nx+d*ny;

                        rx=c-2*dp*nx,ry=d-2*dp*ny;
                        
                        f0=Math.pow((IoR-1)/(IoR+1),2);
                        
                        fth=f0+(1-f0)*Math.pow((1+dp),5);


                        k=1.0-IoR*IoR*(1.0-dp*dp); // calc this first.
                        
                        if(k<0){ // Total Reflection = ZEN-HANSHA
                            rayTrace(p,q,rx,ry,alpha*0.8);
                            //rayTrace(p,q,rx,ry,alpha*1); <- this is rather correct, but makes the flash so heavy.
                        }else{
                            rayTrace(p,q,rx,ry,alpha*fth);
    
                            rx=IoR*c-(IoR*dp+Math.sqrt(k))*nx;
    
                            ry=IoR*d-(IoR*dp+Math.sqrt(k))*ny;
    
                            rayTrace(p,q,rx,ry,alpha*(1-fth));
                        }

                        f=true;

                    }

                }

            }else{

                if(D>0){

                    t=-Math.sqrt(D)-a*c-b*d;

                    if(t>0){

                        p=a+c*t,q=b+d*t;

                        spr.graphics.lineTo(p,q);

                        le=Math.sqrt(p*p+q*q);

                        nx=p/le,ny=q/le;

                        dp=c*nx+d*ny;

                        rx=c-2*dp*nx,ry=d-2*dp*ny;

                        f0=Math.pow((1/IoR-1)/(1/IoR+1),2);

                        fth=f0+(1-f0)*Math.pow((1+dp),5);

                        rayTrace(p,q,rx,ry,alpha*fth);

                        k=1.0-1/(IoR*IoR)*(1.0-dp*dp);

                        if(k>0){

                            rx=1/IoR*c-(1/IoR*dp+Math.sqrt(k))*nx;

                            ry=1/IoR*d-(1/IoR*dp+Math.sqrt(k))*ny;

                            rayTrace(p,q,rx,ry,alpha*(1-fth));

                        }

                        f=true;

                    }

                }

                if(!f){

                    spr.graphics.lineTo(a+c*1000,b+d*1000);

                }

            }

        }

    }

}