26
2016
05

点到线段的最短距离

点到线段的最短距离,比点到直线的最短距离要麻烦一点。点到直线的最短距离,只需要算出点到直线的垂线的长度即可,但是点到线段的最短距离,还要判断垂足是否在线段上,如果垂足不在线段上,最短距离应该为点到线段的两个端点的距离中较小的那一个。

求垂足,求距离,判断点在线段上,都不算太难,只是比较麻烦。

遇到几何问题,我们一般都会想到面积法、向量法。

搜到一个比较简单的方法,用的向量法,代码很少,计算也很简单:http://blog.sina.com.cn/s/blog_5d5c80840101bnhw.html。需要注意,这篇文章中代码的最后一句是错的,评论里边指出了正确的代码。

做了一个demo,看一下效果。

获得 Adobe Flash Player

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;
			}
		}
		//
	}
	
}

源码打包下载

« 上一篇下一篇 »

相关文章:

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

发表评论:

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