问题来源: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;
}
}
}
}
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。