27
2016
04

曲线平滑算法

参考:几个简单的数据点平滑处理算法,用as3.0做了个demo。

先看效果。

获得 Adobe Flash Player

平滑算法函数如下:

HSmooth.as

package
{
	
	public class HSmooth
	{
		public function HSmooth()
		{
			throw(new Error("静态类,不可以实例化,请直接使用类中的静态函数。"));
		}
		
		/**
		 * 三点线性平滑
		 * @param	arr		源数据
		 * @param	m		循环次数
		 * @return	Array	平滑后数据
		 */
		public static function linearSmooth3(arr:Array, m:int = 1):Array
		{
			var i:int, j:int, n:int = arr.length, out:Array = [];
			if (n < 3)
			{
				out = clone(arr);
			}
			else
			{
				var a:Array = arr;
				for (j = 0; j < m; j++)
				{
					out[0] = (5.0 * a[0] + 2.0 * a[1] - a[2]) / 6.0;
					for (i = 1; i <= n - 2; i++)
					{
						out[i] = (a[i - 1] + a[i] + a[i + 1]) / 3.0;
					}
					out[n - 1] = (5.0 * a[n - 1] + 2.0 * a[n - 2] - a[n - 3]) / 6.0;
					a = clone(out);
				}
			}
			return out;
		}
		
		/**
		 * 五点线性平滑
		 * @param	arr		源数据
		 * @param	m		循环次数
		 * @return	Array	平滑后数据
		 */
		public static function linearSmooth5(arr:Array, m:int = 1):Array
		{
			var i:int, j:int, n:int = arr.length, out:Array = [];
			if (n < 5)
			{
				out = clone(arr);
			}
			else
			{
				var a:Array = arr;
				for (j = 0; j < m; j++)
				{
					out[0] = (3.0 * a[0] + 2.0 * a[1] + a[2] - a[4]) / 5.0;
					out[1] = (4.0 * a[0] + 3.0 * a[1] + 2 * a[2] + a[3]) / 10.0;
					for (i = 2; i <= n - 3; i++)
					{
						out[i] = (a[i - 2] + a[i - 1] + a[i] + a[i + 1] + a[i + 2]) / 5.0;
					}
					out[n - 2] = (4.0 * a[n - 1] + 3.0 * a[n - 2] + 2 * a[n - 3] + a[n - 4]) / 10.0;
					out[n - 1] = (3.0 * a[n - 1] + 2.0 * a[n - 2] + a[n - 3] - a[n - 5]) / 5.0;
					a = clone(out);
				}
			}
			return out;
		}
		
		/**
		 * 七点线性平滑
		 * @param	arr		源数据
		 * @param	m		循环次数
		 * @return	Array	平滑后数据
		 */
		public static function linearSmooth7(arr:Array, m:int = 1):Array
		{
			var i:int, j:int, n:int = arr.length, out:Array = [];
			if (n < 7)
			{
				out = clone(arr);
			}
			else
			{
				var a:Array = arr;
				for (j = 0; j < m; j++)
				{
					out[0] = (13.0 * a[0] + 10.0 * a[1] + 7.0 * a[2] + 4.0 * a[3] + a[4] - 2.0 * a[5] - 5.0 * a[6]) / 28.0;
					out[1] = (5.0 * a[0] + 4.0 * a[1] + 3 * a[2] + 2 * a[3] + a[4] - a[6]) / 14.0;
					out[2] = (7.0 * a[0] + 6.0 * a[1] + 5.0 * a[2] + 4.0 * a[3] + 3.0 * a[4] + 2.0 * a[5] + a[6]) / 28.0;
					for (i = 3; i <= n - 4; i++)
					{
						out[i] = (a[i - 3] + a[i - 2] + a[i - 1] + a[i] + a[i + 1] + a[i + 2] + a[i + 3]) / 7.0;
					}
					out[n - 3] = (7.0 * a[n - 1] + 6.0 * a[n - 2] + 5.0 * a[n - 3] + 4.0 * a[n - 4] + 3.0 * a[n - 5] + 2.0 * a[n - 6] + a[n - 7]) / 28.0;
					out[n - 2] = (5.0 * a[n - 1] + 4.0 * a[n - 2] + 3.0 * a[n - 3] + 2.0 * a[n - 4] + a[n - 5] - a[n - 7]) / 14.0;
					out[n - 1] = (13.0 * a[n - 1] + 10.0 * a[n - 2] + 7.0 * a[n - 3] + 4 * a[n - 4] + a[n - 5] - 2 * a[n - 6] - 5 * a[n - 7]) / 28.0;
					a = clone(out);
				}
			}
			return out;
		}
		
		/**
		 * 五点二次平滑
		 * @param	arr		源数据
		 * @param	m		循环次数
		 * @return	Array	平滑后数据
		 */
		public static function quadraticSmooth5(arr:Array, m:int = 1):Array
		{
			var i:int, j:int, n:int = arr.length, out:Array = [];
			if (n < 5)
			{
				out = clone(arr);
			}
			else
			{
				var a:Array = arr;
				for (j = 0; j < m; j++)
				{
					out[0] = (31.0 * a[0] + 9.0 * a[1] - 3.0 * a[2] - 5.0 * a[3] + 3.0 * a[4]) / 35.0;
					out[1] = (9.0 * a[0] + 13.0 * a[1] + 12 * a[2] + 6.0 * a[3] - 5.0 * a[4]) / 35.0;
					for (i = 2; i <= n - 3; i++)
					{
						out[i] = (-3.0 * (a[i - 2] + a[i + 2]) + 12.0 * (a[i - 1] + a[i + 1]) + 17 * a[i]) / 35.0;
					}
					out[n - 2] = (9.0 * a[n - 1] + 13.0 * a[n - 2] + 12.0 * a[n - 3] + 6.0 * a[n - 4] - 5.0 * a[n - 5]) / 35.0;
					out[n - 1] = (31.0 * a[n - 1] + 9.0 * a[n - 2] - 3.0 * a[n - 3] - 5.0 * a[n - 4] + 3.0 * a[n - 5]) / 35.0;
					a = clone(out);
				}
			}
			return out;
		}
		
		/**
		 * 七点二次平滑
		 * @param	arr		源数据
		 * @param	m		循环次数
		 * @return	Array	平滑后数据
		 */
		public static function quadraticSmooth7(arr:Array, m:int = 1):Array
		{
			var i:int, j:int, n:int = arr.length, out:Array = [];
			if (n < 7)
			{
				out = clone(arr);
			}
			else
			{
				var a:Array = arr;
				for (j = 0; j < m; j++)
				{
					out[0] = (32.0 * a[0] + 15.0 * a[1] + 3.0 * a[2] - 4.0 * a[3] - 6.0 * a[4] - 3.0 * a[5] + 5.0 * a[6]) / 42.0;
					out[1] = (5.0 * a[0] + 4.0 * a[1] + 3.0 * a[2] + 2.0 * a[3] + a[4] - a[6]) / 14.0;
					out[2] = (1.0 * a[0] + 3.0 * a[1] + 4.0 * a[2] + 4.0 * a[3] + 3.0 * a[4] + 1.0 * a[5] - 2.0 * a[6]) / 14.0;
					for (i = 3; i <= n - 4; i++)
					{
						out[i] = (-2.0 * (a[i - 3] + a[i + 3]) + 3.0 * (a[i - 2] + a[i + 2]) + 6.0 * (a[i - 1] + a[i + 1]) + 7.0 * a[i]) / 21.0;
					}
					out[n - 3] = (1.0 * a[n - 1] + 3.0 * a[n - 2] + 4.0 * a[n - 3] + 4.0 * a[n - 4] + 3.0 * a[n - 5] + 1.0 * a[n - 6] - 2.0 * a[n - 7]) / 14.0;
					out[n - 2] = (5.0 * a[n - 1] + 4.0 * a[n - 2] + 3.0 * a[n - 3] + 2.0 * a[n - 4] + a[n - 5] - a[n - 7]) / 14.0;
					out[n - 1] = (32.0 * a[n - 1] + 15.0 * a[n - 2] + 3.0 * a[n - 3] - 4.0 * a[n - 4] - 6.0 * a[n - 5] - 3.0 * a[n - 6] + 5.0 * a[n - 7]) / 42.0;
					a = clone(out);
				}
			}
			return out;
		}
		
		/**
		 * 五点三次平滑
		 * @param	arr		源数据
		 * @param	m		循环次数
		 * @return	Array	平滑后数据
		 */
		public static function cubicSmooth5(arr:Array, m:int = 1):Array
		{
			var i:int, j:int, n:int = arr.length, out:Array = [];
			if (n < 5)
			{
				out = clone(arr);
			}
			else
			{
				var a:Array = arr;
				for (j = 0; j < m; j++)
				{
					out[0] = (69.0 * a[0] + 4.0 * a[1] - 6.0 * a[2] + 4.0 * a[3] - a[4]) / 70.0;
					out[1] = (2.0 * a[0] + 27.0 * a[1] + 12.0 * a[2] - 8.0 * a[3] + 2.0 * a[4]) / 35.0;
					for (i = 2; i <= n - 3; i++)
					{
						out[i] = (-3.0 * (a[i - 2] + a[i + 2]) + 12.0 * (a[i - 1] + a[i + 1]) + 17.0 * a[i]) / 35.0;
					}
					out[n - 2] = (2.0 * a[n - 5] - 8.0 * a[n - 4] + 12.0 * a[n - 3] + 27.0 * a[n - 2] + 2.0 * a[n - 1]) / 35.0;
					out[n - 1] = (-a[n - 5] + 4.0 * a[n - 4] - 6.0 * a[n - 3] + 4.0 * a[n - 2] + 69.0 * a[n - 1]) / 70.0;
					a = clone(out);
				}
			}
			return out;
		}
		
		/**
		 * 七点三次平滑
		 * @param	arr		源数据
		 * @param	m		循环次数
		 * @return	Array	平滑后数据
		 */
		public static function cubicSmooth7(arr:Array, m:int = 1):Array
		{
			var i:int, j:int, n:int = arr.length, out:Array = [];
			if (n < 7)
			{
				out = clone(arr);
			}
			else
			{
				var a:Array = arr;
				for (j = 0; j < m; j++)
				{
					out[0] = (39.0 * a[0] + 8.0 * a[1] - 4.0 * a[2] - 4.0 * a[3] + 1.0 * a[4] + 4.0 * a[5] - 2.0 * a[6]) / 42.0;
					out[1] = (8.0 * a[0] + 19.0 * a[1] + 16.0 * a[2] + 6.0 * a[3] - 4.0 * a[4] - 7.0 * a[5] + 4.0 * a[6]) / 42.0;
					out[2] = (-4.0 * a[0] + 16.0 * a[1] + 19.0 * a[2] + 12.0 * a[3] + 2.0 * a[4] - 4.0 * a[5] + 1.0 * a[6]) / 42.0;
					for (i = 3; i <= n - 4; i++)
					{
						out[i] = (-2.0 * (a[i - 3] + a[i + 3]) + 3.0 * (a[i - 2] + a[i + 2]) + 6.0 * (a[i - 1] + a[i + 1]) + 7.0 * a[i]) / 21.0;
					}
					out[n - 3] = (-4.0 * a[n - 1] + 16.0 * a[n - 2] + 19.0 * a[n - 3] + 12.0 * a[n - 4] + 2.0 * a[n - 5] - 4.0 * a[n - 6] + 1.0 * a[n - 7]) / 42.0;
					out[n - 2] = (8.0 * a[n - 1] + 19.0 * a[n - 2] + 16.0 * a[n - 3] + 6.0 * a[n - 4] - 4.0 * a[n - 5] - 7.0 * a[n - 6] + 4.0 * a[n - 7]) / 42.0;
					out[n - 1] = (39.0 * a[n - 1] + 8.0 * a[n - 2] - 4.0 * a[n - 3] - 4.0 * a[n - 4] + 1.0 * a[n - 5] + 4.0 * a[n - 6] - 2.0 * a[n - 7]) / 42.0;
					a = clone(out);
				}
			}
			return out;
		}
		
		/**
		 * 复制数组
		 * @param	arr
		 * @return
		 */
		private static function clone(arr:Array):Array
		{
			var i:int, n:int = arr.length, out:Array = [];
			for (i = 0; i < n; i++)
			{
				out[i] = arr[i];
			}
			return out;
		}
	}
}

源码打包下载

« 上一篇下一篇 »

相关文章:

闪电效果  (2017-11-28 15:4:19)

线段与椭圆的交点  (2017-1-6 14:43:41)

as3录制swf并保存flv视频  (2016-12-28 8:43:41)

解九连环  (2016-12-1 20:58:11)

as3实现setTimeout和trace  (2016-11-10 16:47:37)

registerCursor注册系统光标  (2016-9-14 9:49:40)

鼠标光标管理  (2016-9-13 17:44:3)

变形框(transform)实现  (2016-9-13 16:56:6)

flash文本消除锯齿不显示  (2016-8-25 11:43:31)

greenSock的easing曲线  (2016-8-24 18:30:11)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。