在视锥的另一端计算代理

Computing an agent on the further ends of cone of vision


给定:

在上图中,描绘了蓝色特工的视锥。我想计算与视锥两端相交的灰墙,即右侧和 left.Also 之间的一堵灰色墙,我能否以某种方式计算该点的 x-coordinate。不是灰色代理的坐标,因为那是一个近似值。

计算:

视锥极点与灰海龟相交的 x 坐标。或者他们相交的那些灰海龟。

粗略图:

所以我想计算下图中的x_1和x_2。 一种方法可以按照@JenB 的建议将其分为三种情况,并在每种情况下计算 A。(主要在左侧或右侧)。然后使用三角函数。我是对的。还有其他方法吗?

如果这是一个二维问题,那只是一个相交线的问题。

我会避免使用多个案例;这很容易出错。

您将有一条线描述您的海龟墙,两条线描述您的 FOV 边界。您可以将这三行中的每一条以参数形式表示为 [o.x,o.y] + [v.x, v.y] * s,这是一个不动点 [o.x,o.y] 加法向量 [v.x,v.y] 缩放 s.

乌龟墙仅针对's'的某个域定义;假设 wall.s 的域 = [0 到 0.4,0.6 到 1]

我会描述如何找到交点,但是参数化 2D 线的交点是非常标准的票价,最好以 PDF 格式显示,所以我会向您推荐这个... http://www.ahinson.com/algorithms_general/Sections/Geometry/ParametricLineIntersection.pdf (切记千万不要除以零)

一旦知道了比例参数'left.wall.s'和'right.wall.s'的值,就可以判断海龟墙的范围是否在玩家的视野范围内。您也可以简单地通过插入参数线公式来确定交点。

dwn 的回答包括计算精确的交点。

你说你也有兴趣找出答案所在的补丁。这是代码:

to setup
  clear-all
  create-turtles 1 [
    set heading -30 + random 60
  ]
  ask turtles [
    ;; show center of vision cone
    ask boundary-patch [ set pcolor red ]
    ;; show edges of 20 degree vision cone
    lt 10
    ask boundary-patch [ set pcolor blue ]
    rt 20
    ask boundary-patch [ set pcolor blue ]
    ;; restore turtle's original heading
    lt 10
  ]
end

;; answers the question, what patch on the top row of the
;; world is the turtle currently facing?

to-report boundary-patch  ;; turtle procedure
  let n 0
  while [true] [
    let target patch-ahead n
    if target = nobody or [pycor = max-pycor] of target [
      report target
    ]
    set n n + 1
  ]
end

示例结果:

当然,通过公式直接计算答案实际上在计算上更有效。 (最后有一个可选的舍入步骤,具体取决于您是想要一个点还是一个补丁。)但是这段代码展示了如何做到这一点,而无需进行任何棘手的数学运算。

以下三角函数方法(由@JenB 建议)非常有效:

 to-report calx2 [x0 y0 x1 y1 A]
      report x0 + (y1 - y0) * tan ( A + atan (x1 - x0) (y1 - y0))
    end

to start    
  ask turtles[
         set corner-1 list calx2  xcor ycor ([pxcor] of patch-goal)([pycor] of patch-goal - 0.4) (-45) ([pycor] of patch-goal - 0.4) 
         set corner-2 list calx2  xcor ycor ([pxcor] of patch-goal)([pycor] of patch-goal - 0.4) ( 45) ([pycor] of patch-goal - 0.4) 

    ]

当左边超过180,右边超过0时,问题就出现了。我没有考虑这种情况。不管怎样,上面的代码解决了问题。