27
2015
08

点在直线上运动

问题来源:http://bbs.9ria.com/thread-434920-1-1.html

问题描述:有3个点A,B,C     A,B两点组成一条直线,可以拖动这两点改变直线长度、角度和位置;C点也可以拖动。问题:1,拖动A,B两点的时候,怎么样让C点一直在AB这条线上;
2,拖动A,B两点的时候,AB这条线有时候会和水平线成一定角度,这时,拖动C点时,怎么样才能保证C点在AB线上运动。

问题分析:现在的问题主要是C点,C点有两种运动方式:一种是当拖动AB,C点被动更新位置;一种是拖动C点,主动更新位置。
先看第一种,你需要增加一些限制条件,比如拖动A点时,CB两点间的距离固定,拖动B点时,CA两点间的距离固定,或者其它限制条件。
第二种,需要定义规则,比如拖动C点时,C点的x坐标和鼠标的x坐标相同;或者C点的y坐标和鼠标的y坐标相同;或者C点和鼠标到AB线的垂足重合;或者其他规则。
剩下的就是几何运算了。

获得 Adobe Flash Player
package  {
     
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
     
     
    public class Main extends MovieClip {
         
         
        public function Main() {
            // constructor code
            stage?initStage(null):addEventListener(Event.ADDED_TO_STAGE, initStage);
        }
         
        private function initStage(e:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, initStage);
             
            var A:Sprite = createPoint(5, 0x00ff00);
            var B:Sprite = createPoint(5, 0x00ff00);
            var C:Sprite = createPoint(5, 0xff0000);
            addChild(A);
            addChild(B);
            addChild(C);
            A.x = 100;
            B.x = 400;
            C.x = 200;
            A.y = B.y = C.y =  100; 
            A.buttonMode = B.buttonMode = C.buttonMode = true;
            A.name = "A";
            B.name = "B";
            C.name = "C";
             
            var ic:Sprite = new Sprite();//虚拟的c点,拖动c点时用来计算c点的坐标。
            addChild(ic);
            /*
            ic.graphics.lineStyle(1, 0x000000, 1);
            ic.graphics.moveTo(0, 0);
            ic.graphics.lineTo(100, 0);
            */
             
            var pa:Point = new Point();
            var pb:Point = new Point();
            var pc:Point = new Point();
            updateP();
             
            drag(A);
            drag(B);
            drag(C);
             
            var curDragSp:Sprite;
            /**
             * 拖动时,根据拖动的目标,做出相应的响应。
             */
            function mouseMove():void {
                if (!curDragSp) return;
                switch(curDragSp.name) {
                    case "A":
                        A.x = mouseX;
                        A.y = mouseY;
                        updateCbyA();
                        break;
                    case "B":
                        B.x = mouseX;
                        B.y = mouseY;
                        updateCbyB();
                        break;
                    case "C":
                        updateC();
                        break;
                }
            }
            /**
             * 拖动
             * @param   sp
             */
            function drag(sp:Sprite):void {
                sp.addEventListener(MouseEvent.MOUSE_DOWN, dragHandler);
            }
            function dragHandler(e:Event):void {
                switch(e.type) {
                    case MouseEvent.MOUSE_DOWN:
                        curDragSp = e.currentTarget as Sprite;
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, dragHandler);
                        stage.addEventListener(MouseEvent.MOUSE_UP, dragHandler);
                        stage.addEventListener(Event.MOUSE_LEAVE, dragHandler);
                        break;
                    case MouseEvent.MOUSE_MOVE:
                        mouseMove();
                        break;
                    default:
                        curDragSp = null;
                        stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragHandler);
                        stage.removeEventListener(MouseEvent.MOUSE_UP, dragHandler);
                        stage.removeEventListener(Event.MOUSE_LEAVE, dragHandler);
                        break;
                }
            }
            /**
             * 拖动A点时,更新C点坐标
             * CB/AB比值保持不变
             */
            function updateCbyA():void {
                var cb:Number = Point.distance(pc, pb);
                var ab:Number = Point.distance(pa, pb);
                var f:Number = ab==0?0:(cb / ab);
                updateP();
                ab = Point.distance(pa, pb)
                pc=Point.interpolate(pa, pb, f);
                C.x = pc.x;
                C.y = pc.y;
            }
            /**
             * 拖动B点时,更新C点坐标
             * CA/AB比值保持不变
             */
            function updateCbyB():void {
                var ca:Number = Point.distance(pc, pa);
                var ab:Number = Point.distance(pa, pb);
                var f:Number = ab==0?0:(ca / ab);
                updateP();
                ab = Point.distance(pa, pb);
                pc=Point.interpolate(pb, pa, f);
                C.x = pc.x;
                C.y = pc.y;
            }
             
            /**
             * 拖动c时,更新c的坐标
             */
            function updateC():void {
                ic.x = A.x;
                ic.y = A.y;
                ic.rotation = 180 * Math.atan2(B.y - A.y, B.x - A.x) / Math.PI;
                var d:Number = Point.distance(pa, pb);
                var lx:Number = ic.mouseX;
                if (lx > d) lx = d;
                if (lx < 0) lx = 0;
                var p:Point = new Point(lx, 0);
                pc = ic.localToGlobal(p);
                C.x = pc.x;
                C.y = pc.y;
            }
             
            function updateP():void {
                pa.setTo(A.x, A.y);
                pb.setTo(B.x, B.y);
                pc.setTo(C.x, C.y);
            }
            /**
             * 创建一个圆
             * @param   r
             * @param   co
             * @return
             */
            function createPoint(r:int,co:uint):Sprite {
                var sp:Sprite = new Sprite();
                sp.graphics.lineStyle(1, co, 1);
                sp.graphics.beginFill(co, 1);
                sp.graphics.drawCircle(0, 0, r);
                sp.graphics.endFill();
                return sp;
            }
        }
    }
     
}

源码打包下载

« 上一篇下一篇 »

相关文章:

闪电效果  (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)

发表评论:

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