「转」如何知道直线距离有没有障碍物

「引」 http://bbs.9ria.com/thread-61774-1-8.html



 


一个平面上有2个mc,分别代表玩家和敌人,暂时把这个平面地图用二维数组表示吧,黑色表示障碍,红色表示敌人,绿色表示玩家,如果红色和绿色的连线没有经过黑色障碍物,则说明敌人发现了玩家,问题是我该如何确定红色和绿色的连线中有没有经过障碍物呢?



 
像这样,他们连线经过了黑色障碍物,就表示没有被发现


 

这样就表示发现了



大家有什么好的办法?之前在AS板块问了下,说是求直线方程,还要遍历每个格子,还要求格子四个顶点是否经过直线,太麻烦了,有没有更好点的办法呢

这个应该是游戏中经常会遇到的问题,也算是游戏的AI吧,敌人如何发现玩家,只要他们的直线距离内没有障碍物

 

sliz 回答

射线方法

 

 

package sliz.math {
	/**
	 * ...
	 * @author sliz http://space.flash8.net/space/?534614
	 */

	import flash.display.Graphics;
	import flash.geom.Point;
	public class RayShape {
		public var vertices:Array;
		public function RayShape(vertices:Array){
			this.vertices = vertices;
		}
		public function move(velocity:Point):void {
			var len:int = vertices.length
			for (var i:int = 0; i < len; i++){
				vertices[i] = vertices[i].add(velocity);
			}
		}
		public function setPosition(position:Point):void {
			var diff:Point = position.subtract(middle());
			var len:int = vertices.length;
			for (var i:int = 0; i < len; i++){
				vertices[i] = vertices[i].add(diff);
			}
		}
		public function middle():Point {
			var mid:Point = new Point();
			var len:int = vertices.length;
			for (var i:int = 0; i < len; i++){
				mid = mid.add(vertices[i]);
			}
			mid.x = mid.x / len;
			mid.y = mid.y / len;
			return mid;
		}
		public function debugDraw(graphics:Graphics):void {
			graphics.lineStyle(0);
			graphics.moveTo(vertices[0].x, vertices[0].y);
			var len:int = vertices.length;
			for (var i:int = 0; i < len; i++){
				graphics.lineTo(vertices[i].x, vertices[i].y);
			}
			graphics.lineTo(vertices[0].x, vertices[0].y);
		}
	}





}

 其它:

 

package  
{
	import flash.geom.Point;
	/**
	 * ...
	 * @author sliz http://space.flash8.net/space/?534614
	 */
	public class GeomMath
	{
		private static const EP:Number = Math.LOG10E;
		
		/**
		 * 判断2点是否相等
		 * @param	p1
		 * @param	p2
		 * @return
		 */
		public static function isEuqalPoint(p1:Point, p2:Point):Boolean {
			return Math.abs(p1.x - p2.x) < EP && Math.abs(p1.y - p2.y) < EP;
		}
		
		/**
		 * 确定两条线段是否相交  
		 * @param	l1
		 * @param	l2
		 * @return
		 */
		public static function isIntersect(p1:Point,p2:Point,p3:Point,p4:Point):Boolean {
			return((Math.max(p1.x,p2.x)>=Math.min(p3.x,p4.x))&&   
					(Math.max(p3.x,p4.x)>=Math.min(p1.x,p2.x))&&   
					(Math.max(p1.y,p2.y)>=Math.min(p3.y,p4.y))&&   
					(Math.max(p3.y,p4.y)>=Math.min(p1.y,p2.y))&&   
					(multiply(p3,p2,p1)*multiply(p2,p4,p1)>=0)&&   
					(multiply(p1,p4,p3)*multiply(p4,p2,p3)>=0));  
		}
		
		/**
		 * 一种线段相交判断函数,当且仅当l1,l2相交并且交点不是l1,l2的端点时函数为true;
		 * @param	l1
		 * @param	l2
		 * @return
		 */
		public static function isIntersect2(p1:Point,p2:Point,p3:Point,p4:Point):Boolean {
			return((isIntersect(p1,p2,p3,p4))&&   
				(!isEuqalPoint(p1,p3))&&   
				(!isEuqalPoint(p1,p4))&&   
				(!isEuqalPoint(p2,p3))&&   
				(!isEuqalPoint(p2,p4)));   
		}
		
		/**
		 * 跨立
		 * 伸出右手手心像上依次穿越sp,ep
		 * @param	sp
		 * @param	ep
		 * @param	op
		 * @return
		 */
		public static function multiply(sp:Point,ep:Point,op:Point):int {
			return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y)); 
		}
		
		/**
		 * 穿越
		 * @param	cn
		 * @param	ln1
		 * @param	ln2
		 * @param	sn
		 * @param	en
		 * @return
		 */
		public static function acrossAble(cn:Point, ln1:Point, ln2:Point, sn:Point, en:Point):Boolean {
			return multiply(ln1,cn,sn) * multiply(cn,ln2,sn) <= 0 && multiply(ln1,cn,en) * multiply(cn,ln2,en) <= 0;
		}
		
		public static function getAcrossPoint(p1:Point, p2:Point, p3:Point, p4:Point,isMax:Boolean=false):Point {
			if (!isMax&&!isIntersect(p1,p2,p3,p4)) {
				return null;
			}
			var p:Point = new Point();
			//y=ax+b
			//y=cx+d
			var type:int = 0;
			if (p1.x==p2.x) {
				//|x=p1.x
				type = 1;
			}else {
				var a:Number = (p1.y - p2.y) / (p1.x - p2.x);
				var b:Number = p1.y - a * p1.x;
			}
			if (p3.x==p4.x) {
				//|x=p1.x
				type = 2;
			}else {
				var c:Number = (p3.y - p4.y) / (p3.x - p4.x);
				var d:Number = p3.y - c * p3.x;
			}
			if (type==0) {
				p.x = (d - b) / (a - c);
				p.y = a * p.x + b;
			}else if (type==1) {
				p.x = p1.x;
				p.y = c * p.x + d;
			}else if (type==2) {
				p.x = p3.x;
				p.y = a * p.x + b;
			}
			return p;
		}
	}
}
 

 

在MATLAB中,可以通过使用无人机的传感器(例如激光雷达或超声波传感器)来实时测量无人机与障碍物之间的距离。 要实现这个功能,首先需要获取传感器的数据。可以使用MATLAB提供的函数,如`readLidarData`或`readDistance`来读取传感器返回的距离值。通过与传感器的连接,可以设置传感器的参数和配置,以确保正确的距离测量。 接下来,可以使用距离测量值来进行实时距离计算。根据无人机的当前位置和姿态,可以使用几何计算方法来估计无人机与障碍物之间的距离。例如,在笛卡尔坐标系中,可以使用欧氏距离公式来计算无人机与障碍物之间的直线距离。 同时,为了实时监测距离变化,可以使用循环来断读取传感器数据、计算距离,并显示或处理相关信息。例如,可以在MATLAB图形界面上显示距离信息或在控制台输出距离值。还可以设置阈值,以便在距离接近预设值时触发警报或采取其他行动。 最后,为确保实时性和精度,还可以使用MATLAB的并行计算功能来优化计算和数据处理过程。这样可以加快距离计算和显示的速度,使得无人机与障碍物距离监测更加准确和及时。 总之,MATLAB提供了强大的功能和工具,可以帮助我们实时监测无人机与障碍物之间的距离。通过合理选择传感器和使用MATLAB的计算和显示功能,可以实现稳定、准确和实时的距离监测系统。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值