经过多个点画曲线

package app{
    import flash.display.Sprite;
    import flash.geom.Point;
    import framework.game.Game;
    import g.objs.MyObj;
    /**
     * var curve:Curve=Curve.create();
     * var curvePoints:Vector.<Point>=curve.createCurve(originPoints);
     * curve.draw(sprite,originPoints,curvePoints);
     */
    public class Curve extends MyObj{
        
        public static function create():Curve{
            var game:Game=Game.getInstance();
            var info:*={};
            return game.createGameObj(new Curve(),info) as Curve;
        }
        
        public function Curve(){
            super();
        }
        
        override protected function init(info:*=null):void{
            super.init(info);
            
        }
        
        /**
         * 创建曲线
         * @param   originPoint 曲线要经过的点列表
         * @param   curveRatio (0,1)曲线的疏密
         * @param   isCap 是否闭合曲线
         * @return 返回曲线上的点列表
         */
        public function createCurve(originPoint:Vector.<Point>,curveRatio:Number=0.1,isCap:Boolean=false):Vector.<Point>{
            //控制点收缩系数 ,经调试0.6较好
            const scale:Number=0.6;
            const originCount:int=originPoint.length;
            var midpoints:Vector.<Point>=new Vector.<Point>();
            //生成中点       
            for(var i:int=0;i<originCount;i++){
                var nexti:int=(i+1)%originCount;
                midpoints[i]=new Point((originPoint[i].x + originPoint[nexti].x)/2.0,
                                       (originPoint[i].y + originPoint[nexti].y)/2.0);
            }
              
            //平移中点  
            var extrapoints:Vector.<Point>=new Vector.<Point>(2 * originCount,true);
            for(i=0;i<extrapoints.length;i++)extrapoints[i]=new Point();
            
            for(i=0;i<originCount;i++){
                nexti=(i+1)%originCount;
                var backi:int=(i+originCount-1)%originCount;
                var midinmid:Point=new Point((midpoints[i].x+midpoints[backi].x)/2.0,
                                             (midpoints[i].y+midpoints[backi].y)/2.0);
                var offsetx:int=originPoint[i].x-midinmid.x;
                var offsety:int=originPoint[i].y-midinmid.y;
                var extraindex:int=2*i;
                extrapoints[extraindex].x=midpoints[backi].x+offsetx;
                extrapoints[extraindex].y=midpoints[backi].y+offsety;
                 //朝 originPoint[i]方向收缩
                var addx:int=(extrapoints[extraindex].x-originPoint[i].x)*scale;
                var addy:int=(extrapoints[extraindex].y-originPoint[i].y)*scale;
                extrapoints[extraindex].x=originPoint[i].x+addx;
                extrapoints[extraindex].y=originPoint[i].y+addy;
                
                var extranexti:int=(extraindex+1)%(2*originCount);
                extrapoints[extranexti].x=midpoints[i].x+offsetx;
                extrapoints[extranexti].y=midpoints[i].y+offsety;
                //朝 originPoint[i]方向收缩
                addx=(extrapoints[extranexti].x-originPoint[i].x)*scale;
                addy=(extrapoints[extranexti].y-originPoint[i].y)*scale;
                extrapoints[extranexti].x=originPoint[i].x+addx;
                extrapoints[extranexti].y=originPoint[i].y+addy;
                
            }
            var curvePoint:Vector.<Point>=new Vector.<Point>();
            var controlPoint:Vector.<Point>=new Vector.<Point>(4,true);
            //生成4控制点,产生贝塞尔曲线  
            for(i=0;i<originCount;i++){
                if(i>=originCount-1&&isCap==false)break;
                   controlPoint[0]=originPoint[i];
                   extraindex=2*i;
                   controlPoint[1]=extrapoints[extraindex + 1];
                   extranexti=(extraindex+2)%(2*originCount);
                   controlPoint[2]=extrapoints[extranexti];
                   nexti=(i+1)%originCount;
                   controlPoint[3]=originPoint[nexti];  
                   var u:Number=1;
                   while(u>=0){
                       var px:int=bezier3funcX(u,controlPoint);
                       var py:int=bezier3funcY(u,controlPoint);
                       //u的步长决定曲线的疏密  
                       u-=curveRatio;
                       var tempP:Point=new Point(px,py);
                       //存入曲线点
                       curvePoint.push(tempP);
                   }
            }
            return curvePoint;
        }
        //三次贝塞尔曲线  
        private function bezier3funcX(uu:Number,controlP:Vector.<Point>):Number{
           var part0:Number=controlP[0].x*uu*uu*uu;
           var part1:Number=3*controlP[1].x*uu*uu*(1-uu);
           var part2:Number=3*controlP[2].x*uu*(1-uu)*(1-uu);
           var part3:Number=controlP[3].x*(1-uu)*(1-uu)*(1-uu);
           return part0+part1+part2+part3;
        }      
        private function bezier3funcY(uu:Number,controlP:Vector.<Point>):Number{
           var part0:Number=controlP[0].y*uu*uu*uu;
           var part1:Number=3*controlP[1].y*uu*uu*(1-uu);
           var part2:Number=3*controlP[2].y*uu*(1-uu)*(1-uu);
           var part3:Number=controlP[3].y*(1-uu)*(1-uu)*(1-uu);
           return part0+part1+part2+part3;
        }
        
        
        public function draw(sp:Sprite,originPoints:Vector.<Point>,curvePoints:Vector.<Point>,isDrawCurveDot:Boolean=true):void{
            const color:uint=0xff0000;
            sp.graphics.lineStyle(1,color);
            for(var i:int=0;i<curvePoints.length;i++){
                if(i>0){
                    sp.graphics.lineTo(curvePoints[i].x,curvePoints[i].y);
                }else{
                    sp.graphics.moveTo(curvePoints[i].x,curvePoints[i].y);
                }
                //
                if(isDrawCurveDot){
                    sp.graphics.drawCircle(curvePoints[i].x,curvePoints[i].y,3);
                }
            }
            
            //draw dot
            sp.graphics.lineStyle(1,0x0000ff,0.5);
            sp.graphics.beginFill(0x0000ff,0.5);
            for(i=0;i<originPoints.length;i++){
                sp.graphics.drawCircle(originPoints[i].x,originPoints[i].y,3);
            }
            sp.graphics.endFill();
        }
        
    };

}

https://blog.csdn.net/hzsjun/article/details/24958773

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值