破晓 发表于 2015-3-2 09:45:29

拟合直线算法

从网上找的一个,


直接上代码:


DynamicDrawer.as

package
{
        //
        /**
       * simple2d.draw.DynamicDrawer
       *
                本类用于动态绘制某些shape
        */
       
        import flash.display.Sprite;
        import flash.geom.Rectangle;
       
        public class DynamicDrawer{
               
                public function DynamicDrawer(){
                        throw Error("Error: org.vily.utils.draw.DynamicDrawer是静态类,不能创建实例");
                }
               
                public static function createByVS(arr:Array):Rectangle {
                        var rect:Rectangle = null;
                        if (arr != null && arr.length > 0) {
                                var len:int = arr.length;
                                rect = new Rectangle();
                                var minV:Object = { x:arr.x, y:arr.y };
                                var maxV:Object = { x:arr.x, y:arr.y };
                                for (var i:int = 1; i < len; i++ ) {
                                        if (arr.x < minV.x) {
                                                minV.x = arr.x;
                                        }else if (arr.x > maxV.x) {
                                                maxV.x = arr.x;
                                        }
                                        //
                                        if (arr.y < minV.y) {
                                                minV.y = arr.y;
                                        }else if (arr.y > maxV.y) {
                                                maxV.y = arr.y;
                                        }
                                }
                                rect.x = minV.x;
                                rect.y = minV.y;
                                rect.width = maxV.x - minV.x;
                                rect.height = maxV.y - minV.y;
                        }
                        return rect;
                }
                public static function clear(spr:Sprite):void{
                        spr.graphics.clear();
                }
               
                /**
                        绘制包含边框和填充的矩形
                */
                public static function drawRect(spr:Sprite,rect:Rectangle,thickness:Number = 1.0, l_color:uint = 0x0,l_alphaNum:Number = 0.5, color:uint = 0x0,alphaNum:Number = 0.5):void{
                        //spr.graphics.clear();
                        spr.graphics.lineStyle(thickness,l_color,l_alphaNum)
                        spr.graphics.beginFill(color,alphaNum);
                        spr.graphics.drawRect(rect.x,rect.y,rect.width,rect.height);
                        spr.graphics.endFill();
                }
               
                //绘制直线
                public static function drawLine(spr:Sprite,posA:Object,posB:Object,thickness:Number = 1.0, l_color:uint = 0x0,l_alphaNum:Number = 0.5):void{
                       
                        spr.graphics.lineStyle(thickness,l_color,l_alphaNum);
                        spr.graphics.moveTo(posA.x, posA.y);
                        spr.graphics.lineTo(posB.x, posB.y);                       
                }
        }
}

Main.as

package
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.geom.Rectangle;
        //
        /**
       * ...
       * @author vilylei
       */
        public class Main extends Sprite
        {
               
                public function Main():void
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }               
               
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                        // entry point
                        // 创建数据
                        var rect:Rectangle = new Rectangle(100, 50, 200, 200);
                        var vs:Array = [];
                        var len:int = 6;
                        for (var i:int = 0; i < len; i++) {
                                vs.push( { x:rect.x + Math.random() * rect.width, y:rect.y + Math.random() * rect.height } );
                                var tr:Rectangle = new Rectangle();
                                tr.x = vs.x - 2;
                                tr.y = vs.y - 2;
                                tr.width = 4;
                                tr.height = 4;
                                DynamicDrawer.drawRect(this, tr);
                        }
                       
                        var pa:Object = { x:0, y:0 };
                        var pb:Object = { x:0, y:0 };
                        linearFitting(vs, len, pa, pb);
                        DynamicDrawer.drawLine(this,pa,pb,2.0,0xff0000);
                }
                //
                /*
               * 直线拟合实现
               * @param                        vs        是一个数组,包含若干待计算点(每一个点是{x:0,y:0}型的Object的对象)
               * @param                        len        是vs数组的长度
               * @param                        pa        是一个as3 Object对象->{x:0,y:0},是计算出来线段的第一个端点
               * @param                        pb        是一个as3 Object对象->{x:0,y:0},是计算出来线段的第二个端点
               * **/
                private function linearFitting(vs:Array,len:int,pa:Object, pb:Object):void {
                        var A:Number = sumVSY( vs );
                        var B:Number = sumVSX( vs );
                        //
                        var C:Number = sumVSXMultY( vs );
                        var D:Number = sumVSXMultX( vs );
                       
                        // 计算出直线的参数k和b(基于:y= k*x + b)
                        var k:Number = (A * B - len * C) / (B * B- len * D);
                        var b:Number = (B * C - A * D) / (B * B - len * D);
                        //
                        var fr:Rectangle = DynamicDrawer.createByVS(vs);
                        pa.x = fr.x;
                        pb.x = fr.right;
                        pa.y = k * pa.x + b;
                        pb.y = k * pb.x + b;
                }
                private function sumVSY(vs:Array):Number {
                        var len:int = vs.length;
                        var tem:Number = 0;
                        for (var i:int = 0; i < len; i++) {
                                tem += vs.y;
                        }
                        return tem;
                }
                private function sumVSX(vs:Array):Number {
                        var len:int = vs.length;
                        var tem:Number = 0;
                        for (var i:int = 0; i < len; i++) {
                                tem += vs.x;
                        }
                        return tem;
                }
                private function sumVSXMultY(vs:Array):Number {
                        var len:int = vs.length;
                        var tem:Number = 0;
                        for (var i:int = 0; i < len; i++) {
                                tem += vs.x * vs.y;
                        }
                        return tem;
                }
                private function sumVSXMultX(vs:Array):Number {
                        var len:int = vs.length;
                        var tem:Number = 0;
                        for (var i:int = 0; i < len; i++) {
                                tem += vs.x * vs.x;
                        }
                        return tem;
                }
                //
        }
       
}


源码:

**** Hidden Message *****

shawn00 发表于 2015-3-2 14:58:47

感謝高水平分享

我是汉子 发表于 2015-3-2 15:12:06

感谢分享,感觉网站有点不稳定

lxz 发表于 2019-2-24 02:54:43

感谢分享!~
页: [1]
查看完整版本: 拟合直线算法