点到线段的最短距离,比点到直线的最短距离要麻烦一点。点到直线的最短距离,只需要算出点到直线的垂线的长度即可,但是点到线段的最短距离,还要判断垂足是否在线段上,如果垂足不在线段上,最短距离应该为点到线段的两个端点的距离中较小的那一个。
求垂足,求距离,判断点在线段上,都不算太难,只是比较麻烦。
遇到几何问题,我们一般都会想到面积法、向量法。
搜到一个比较简单的方法,用的向量法,代码很少,计算也很简单: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; } } // } }
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。