问题描述
简介
一段时间以来,我一直在尝试按照Craig Reynold的here描述的转向行为来实施隔离墙。行为本质上可以归结为网站上的以下描述:
要实施跟踪墙,我们首先要预测车辆的 根据其当前速度在未来短时间内定位 (黑点)。这个未来的位置预计到最近的点 “墙”(红点)。沿着墙从此墙点移出 法线(红线)所需的偏移距离产生目标 点(红色圆圈)。
链接页面上有一个Java小程序,上面展示了上述内容,但是对于那些(大多数人)无法查看的Java小程序,请参见下面的.gif。
我已经很接近了,但是由于某种原因,我的版本仍然略有下降。我的投标人似乎在选择下一个最近的墙像素时遇到麻烦,这导致投影的目标点出现抖动。这个问题非常极端,以至于有时没有一个新的计划就可以将目标赶到目标点。请参阅下面的.gif进行比较。
简要介绍一下boid在我的实现中的运作方式:
- 在每个帧中,boid都会调用
followWall()
。 - 在
followWall()
内,如果boid的成员变量hasHitWall
为False,它将检查boid前面的点是否已降落在墙像素上(boid在其中移动的环境是黑白像素网格,其中黑色=墙)。 - 如果检测到墙像素,它将
hasHitWall
设置为True,并收集墙的所有连接的“边缘像素”,并将它们存储在名为currentEdgePixels
的对象列表中。 li>
- 下一帧,如果
hasHitWall
为True,则该Boid将通过迭代currentEdgePixels
并找到与其position
的距离最短的像素来找到最近的边缘像素。然后,它将拉动该墙像素的法线,并沿着法线向量将点投影一个设定距离。这成为“指导点”。 - 然后,Boid将使用其
seek()
行为来引导转向点(在Craig Reynold的描述中称为目标点)。 - 只要
hasHitWall
保持为True,Boid就会继续在currentEdgePixels
内找到最接近的边缘像素并向其寻找。
简要说明:我完全理解,将壁的所有边缘像素存储在boid对象中并每帧检查每个像素都不理想且效率低下。这是一个临时设计,可以简化调试,一旦一切正常,我可能会重新设计。
代码
我上述行为的代码可以在下面找到。首先,对一些常见元素进行一些简要说明:
pixelGrid
:此参数是代表图像行的列表的列表。表示行的列表中的每个元素都包含1或0,具体取决于该行/列位置的像素颜色是白色还是黑色。
getnormalizedVectorFromOrigin()
:此函数返回一个表示在[-1,1]范围内的单位圆上的矢量的元组。如果将一个向量(或点)传递到其未归一化向量在[-1,1]范围之外的函数中,则在返回之前,将减小所得向量以使其适合于适当范围。 Ex .:(1.7675,-1.7675)的向量将变为(0.707,-0.707)
followWall():
def followWall(self,pixelGrid,screenSize):
if (not self.hasHitWall):
wallCollisionPixel = self.detectWall(pixelGrid,screenSize)
if (wallCollisionPixel):
self.hasHitWall = True
self.currentEdgePixels = utils.findAllEdgePixels(wallCollisionPixel,screenSize)
elif (self.hasHitWall):
wallPixel = self.findClosestEdgePixel(pixelGrid,screenSize)
wallPixelnormal = utils.getEdgePixelnormal(wallPixel,screenSize)
steeringPointdistance = 30
steeringPoint = (int(round(wallPixel[0] + (wallPixelnormal[0] * steeringPointdistance),0)),int(round(wallPixel[1] + (wallPixelnormal[1] * steeringPointdistance),0)))
self.seekPoint = steeringPoint
self.seek(steeringPoint,1)
findClosestEdgePixel():
def findClosestEdgePixel(self,screenSize):
futuredistance = 20
normalizedVeLocity = utils.getnormalizedVectorFromOrigin(self.veLocity.get())
futurePosition = (int(round(self.position.x + (normalizedVeLocity[0] * futuredistance),int(round(self.position.y + (normalizedVeLocity[1] * futuredistance),0)))
closestEdgePixel = self.currentEdgePixels[0]
for edgePixel in self.currentEdgePixels:
if (utils.getdistance(futurePosition,edgePixel) < utils.getdistance(futurePosition,closestEdgePixel)):
closestEdgePixel = edgePixel
return closestEdgePixel
getdistance():
def getdistance(point1,point2):
return math.sqrt(((point2[0] - point1[0]) ** 2) + ((point2[1] - point1[1]) ** 2))
关闭
如果任何人可能对如何使我的实现工作得更好的想法,或者指出我的代码中可能导致此问题的缺陷,我将不胜感激。如果您认为可能有更好的方法来实现这种特殊的转向行为,我也很乐意听到建议。
请告诉我是否可以提供更多信息或部分代码。预先非常感谢。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)