等分贝塞尔曲线工具类

来源:互联网 发布:软件测试工程师月薪 编辑:程序博客网 时间:2024/04/28 20:29
package{import flash.geom.Point;public class Bezier{//  对外变量private static var p0:Point;// 起点private static var p1:Point;// 贝塞尔点private static var p2:Point;// 终点private static var step:uint;// 分割份数//  辅助变量private static var ax:int;private static var ay:int;private static var bx:int;private static var by:int;private static var A:Number;private static var B:Number;private static var C:Number;private static var total_length:Number;// 长度//  速度函数private static function s (t:Number):Number{return Math.sqrt(A * t * t + B * t + C);}//  长度函数private static function L (t:Number):Number{var temp1:Number = Math.sqrt(C + t * (B + A * t));var temp2:Number = (2 * A * t * temp1 + B *(temp1 - Math.sqrt(C)));var temp3:Number = Math.log(B + 2 * Math.sqrt(A) * Math.sqrt(C));var temp4:Number = Math.log(B + 2 * A * t + 2 * Math.sqrt(A) * temp1);var temp5:Number = 2 * Math.sqrt(A) * temp2;var temp6:Number = (B * B - 4 * A * C) * (temp3 - temp4);return (temp5 + temp6) / (8 * Math.pow(A, 1.5));}//  长度函数反函数,使用牛顿切线法求解private static function InvertL (t:Number, l:Number):Number{var t1:Number = t;var t2:Number;do{t2 = t1 - (L(t1) - l)/s(t1);if (Math.abs(t1-t2) < 0.000001) break;t1 = t2;}while(true);return t2;}//  返回所需总步数public static function init ($p0:Point, $p1:Point, $p2:Point, $speed:Number):uint{p0   = $p0;p1   = $p1;p2   = $p2;//step = 30;ax = p0.x - 2 * p1.x + p2.x;ay = p0.y - 2 * p1.y + p2.y;bx = 2 * p1.x - 2 * p0.x;by = 2 * p1.y - 2 * p0.y;A = 4*(ax * ax + ay * ay);B = 4*(ax * bx + ay * by);C = bx * bx + by * by;//  计算长度total_length = L(1);//  计算步数step = Math.floor(total_length / $speed);if (total_length % $speed > $speed / 2)step ++;trace("曲长:" + total_length);trace("步数:" + step);return step;}// 根据指定nIndex位置获取锚点:返回坐标和角度public static function getAnchorPoint (nIndex:Number):Array{if (nIndex >= 0 && nIndex <= step){var t:Number = nIndex/step;//  如果按照线行增长,此时对应的曲线长度var l:Number = t*total_length;//  根据L函数的反函数,求得l对应的t值t = InvertL(t, l);//  根据贝塞尔曲线函数,求得取得此时的x,y坐标var xx:Number = (1 - t) * (1 - t) * p0.x + 2 * (1 - t) * t * p1.x + t * t * p2.x;var yy:Number = (1 - t) * (1 - t) * p0.y + 2 * (1 - t) * t * p1.y + t * t * p2.y;//  获取切线var Q0:Point = new Point((1 - t) * p0.x + t * p1.x, (1 - t) * p0.y + t * p1.y);var Q1:Point = new Point((1 - t) * p1.x + t * p2.x, (1 - t) * p1.y + t * p2.y);//  计算角度var dx:Number = Q1.x - Q0.x;var dy:Number = Q1.y - Q0.y;var radians:Number = Math.atan2(dy, dx);var degrees:Number = radians * 180 / Math.PI;return new Array(xx, yy, degrees);}else{return [];}}}}

原创粉丝点击