点到线段的最短距离,比点到直线的最短距离要麻烦一点。点到直线的最短距离,只需要算出点到直线的垂线的长度即可,但是点到线段的最短距离,还要判断垂足是否在线段上,如果垂足不在线段上,最短距离应该为点到线段的两个端点的距离中较小的那一个。
求垂足,求距离,判断点在线段上,都不算太难,只是比较麻烦。
遇到几何问题,我们一般都会想到面积法、向量法。
搜到一个比较简单的方法,用的向量法,代码很少,计算也很简单:http://blog.sina.com.cn/s/blog_5d5c80840101bnhw.html。需要注意,这篇文章中代码的最后一句是错的,评论里边指出了正确的代码。
做了一个demo,看一下效果。
as代码如下:
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main extends MovieClip {
public var p0:MovieClip;
public var p1:MovieClip;
public var p2:MovieClip;
public function Main() {
// constructor code
drag(p0);
drag(p1);
drag(p2);
update();
}
/**
* 点(px,py)到线段(X1,Y1)-(X2,Y2)的最短距离
* @param X1
* @param Y1
* @param X2
* @param Y2
* @param px
* @param py
* @return
*/
public function distance(x1:Number, y1:Number, x2:Number, y2:Number, px:Number, py:Number):Number {
var cross:Number = (x2 - x1) * (px - x1) + (y2 - y1) * (py - y1);
if (cross<=0) {
return Math.sqrt((px - x1) * (px - x1) + (py - y1) * (py - y1));
}
var d2:Number = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (cross>=d2) {
return Math.sqrt((px - x2) * (px - x2) + (py - y2) * (py - y2));
}
var r:Number = cross / d2;
var dx:Number = x1 + (x2 - x1) * r;
var dy:Number = y1 + (y2 - y1) * r;
return Math.sqrt((px - dx) * (px - dx) + (py - dy) * (py - dy));
}
/**
* 刷新显示
*/
public function update():void {
graphics.clear();
graphics.lineStyle(2, 0xff0000);
graphics.moveTo(p0.x, p0.y);
graphics.lineTo(p1.x, p1.y);
var r:Number = distance(p0.x, p0.y, p1.x, p1.y, p2.x, p2.y);
graphics.lineStyle(1, 0x0000ff);
graphics.drawCircle(p2.x, p2.y, r);
}
//-----------------拖动----------------
private var curSp:Sprite;
private function drag(sp:Sprite):void {
sp.addEventListener(MouseEvent.MOUSE_DOWN, dragHandler);
sp.buttonMode = true;
}
private function dragHandler(e:Event):void
{
switch(e.type) {
case MouseEvent.MOUSE_DOWN:
curSp = e.currentTarget as Sprite;
curSp.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, dragHandler);
stage.addEventListener(Event.MOUSE_LEAVE, dragHandler);
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragHandler);
break;
case MouseEvent.MOUSE_MOVE:
update();
break;
default:
curSp.stopDrag();
curSp = null;
stage.removeEventListener(MouseEvent.MOUSE_UP, dragHandler);
stage.removeEventListener(Event.MOUSE_LEAVE, dragHandler);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragHandler);
break;
}
}
//
}
}
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。