zoukankan      html  css  js  c++  java
  • 经过多个点画曲线

    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

  • 相关阅读:
    P1311 选择客栈 模拟 ( + st表)
    P2656 采蘑菇 tarjan + spfa
    送别
    10.16互测题 贪心+数论
    poj 2823 Sliding Window 单调队列
    P1036 选数 dfs
    P3370 【模板】字符串哈希
    A Tear or A Smile?
    KMP 算法
    jQuery 中 attr 和 prop 的区别
  • 原文地址:https://www.cnblogs.com/kingBook/p/10214099.html
Copyright © 2011-2022 走看看