问题来源: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线的垂足重合;或者其他规则。
剩下的就是几何运算了。
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; } } } }
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。