5

添加信息:

我正在使用广场的内部作为竞技场。启动时,方块在随机位置和旋转中生成,我无法访问任何方块属性。

然后我在广场内有一个移动的物体,我正在为它构建人工智能,我希望这个物体“了解”竞技场墙壁的位置。每次物体撞到墙上时,我都会得到一个触摸返回,所以我知道它是否击中。我正在使用它来映射物体撞击墙壁的全局位置并保存它......在同一面墙上击中 3 次后,我想在数学上“画一条直线”沿着那些代表竞技场墙壁的点- 有了这个,我可以告诉我的对象不要靠近这些坐标。

3个点的原因?好吧,如果物体撞到墙的一侧,然后撞到墙的另一侧,我会从一侧到另一侧画一条线,给出关于墙在哪里的错误数据。

如果 Java 看到三个(或更多)内联点,它就知道该对象撞到了同一堵墙上(或者更远一些)。

继续:

我正在尝试使用给定的坐标数据绘制线条。基本上我有一个包含 X 和 Y 坐标的数组,我希望能够在数学上检测它们是否构成一条直线(给定或取几个像素)。(坐标是正方形的边界)

例如,数组可能是这样的:

[x0][y0] - 1,1

[x1][y1] - 2,2

[x2][y2] - 5,5

这将呈现正方形一侧的对角线,如下所示:

在此处输入图像描述

但有时我可能会得到正方形一侧的一个坐标,然后是另一侧的坐标,所有这些都混合在一起(也不一定是 90 度角!)。所以我希望能够遍历数组,并检测什么坐标构成一条线(或正方形的边界边),如下所示:

在此处输入图像描述

所以现在,我有一个二维数组:

private double wallLocations[][] = new double[10][10];

和一个不起作用的while循环。我什至不知道从哪里开始:

for(int r = 0; r < wallIndex; r++){
            for(int c = 0; c < wallIndex; c++){

                int index = 0;
                if(wallLocations[r][index] == wallLocations[r][c] && wallLocations[r][index + 1] == wallLocations[r][c] &&
                        wallLocations[r][index + 2] == wallLocations[r][c]){

                    System.out.println("***** Wall Here! *****");
                    index++;
                }

            }
        }

- - 更新 - -

这是我正在寻找的一个更好的例子。红点代表进入的坐标,当 3 个或更多点排列时检测到一条线(如果是 2 个点,那么它会检测到任何一个点)......你注意到这开始看起来像边界一个正方形?

在此处输入图像描述

4

2 回答 2

2

这似乎本质上是一个聚类问题,而且这些问题通常非常困难。聚类很难的部分原因是可能有不止一个适用的映射。

例如(请原谅我糟糕的 ascii 艺术):

 X   X   X  

   X   X   X

 X   X   X   X   

可以映射

 X---X---X          X   X   X 
                     \ / \ / \ 
   X---X---X   or     X   X   X
                     / \ / \   \
 X---X---X---X      X   X   X   X 

我已经看到使用混合高斯模型的期望最大化算法用于这种事情(当有很多点但只有几条预期线时),但你通常必须给该算法一定数量的集群,虽然它的结果很好,但它是一个相当慢的算法,可能需要多次迭代。我有点想我已经看到了一些通常更快的东西,那就是某种图像处理算法,但我必须做一些研究。

我有点想知道你在哪里找到每对点的 y=mx+b 并且它们对 m 和 b 进行排序。为每对找到 [0,pi) 中的角度 θ 并在角度而不是 m 上进行排序可能是有利的,或者可能更好地通过集群进行排序cos(2θ)——这点是线组 {y= -0.0001 x + 1, y =1, and y=0.0001x + 1} 非常相似,线组{y= -10000x + 10, x = 0, and y=10000x - 10} 也非常相似,但是cos (2θ) 应该使它们尽可能地分开,因为每组之间的任何两对应该几乎垂直。

另请注意,在我的示例中,b 对于几乎垂直于 x 轴的线并不重要,因此“b”对于直接聚类可能不是那么有用。

我想,也许,两条线之间可能有一些可用的“距离”度量,我只是不确定它会是什么。两条几乎平行的线“在屏幕上”会聚(点通常在哪里)可能应该被认为是“更接近”,而不是它们会聚到距离屏幕一万亿个单位的地方——或者他们应该这样做吗?纯粹地说,如果三条线都不平行(如果它们在一个平面上,它们都会在某个地方相遇),则永远不能成对地认为它们彼此更接近,但直观地说,如果我们有两条线通常是一英寸除了在我们关注的区域之外,我们会选择在关注区域相距一英里的两条相同指向的线上更接近的那对。这让我觉得也许是线条之间的区域,受我们区域的约束* 应该用作度量。

抱歉,我不确定所有这些头脑风暴有多大用处,但它可能会让事情变得不同。

编辑:您知道吗,通过研究可能会找到更好的答案:

http://en.wikipedia.org/wiki/Hough_transform

编辑二和三:

好的,...您刚才描述的情况要简单得多,而且不那么通用(尽管说实话,我认为我误读了您的初始查询比实际情况更通用)。

你有 4 个候选墙。让你的人工智能四处弹跳,直到找到三个共线点。那应该是对组合的简单测试。将这三个点指定为一堵墙。根据您拥有的其他点,您实际上可能能够确定或至少估计其他三堵墙(假设它一个正方形)。如果您在不同的墙上有 5 个点和 3 个点,您应该能够计算出墙之间的距离,从而计算出第四面墙的可能位置。要测试其他两个点是否在不同的墙壁上,请确保它们成对不与垂直或平行于墙壁定义的线的线共线,或者如果它们在平行线上,请测试以查看如果它们之间的距离小于墙与它们之间的距离(如果是这种情况,它们就在与第一个候选墙相对的墙上)。鉴于它们位于不同的墙壁上,要么面对第一个找到的墙壁,要么它们位于垂直于该墙壁的墙壁上。无论哪种方式,您都可以找到定义具有一些棘手几何形状的墙壁的线条。

(实际上,要确定尺寸,我认为您甚至不需要测试就可以看到您有 3 个共线点……我认为您只需要测试就可以看到您已经转了两圈。 . 至少需要 4 分,但如果你不走运,可能会更多。必须确定其中两个点与其他两个点在不同的墙上,这意味着反弹非常大!)

涉及到一些数学问题,今晚我有点太累了,无法进一步解释,而且我不知道你想利用多少正方形周围点的几何形状,因为你不能在更一般的情况下使用这些属性,所以我将保留它,也许稍后还会删除我之前的一些其他头脑风暴。

于 2012-11-24T02:28:10.340 回答
0

如果你有两个点,你可以用 Math.atan2 计算连接线的斜率。

于 2012-11-24T00:07:00.737 回答