Java - 使用给定坐标检测直线

时间:2012-11-23 23:45:07

标签: java eclipse math line angle

添加信息:

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

然后我在广场内有一个移动的物体,我正在建造AI,我希望物体“学习”竞技场的墙壁。每当物体碰到墙壁时,我都会触摸返回,所以我知道它是否被击中。我用这个来映射物体撞到墙壁的地方的全球位置并保存它...在同一墙上的3次点击之后,我想在数学上“画出一条直线”,这些点代表竞技场的墙壁 - 有了这个,我可以告诉我的对象不要靠近这些坐标。

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

如果Java看到内联的三个(或更多)点,则它知道该对象已经碰到了同一个墙(要么是向上还是向上)。

续:

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

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

[x0] [y0] - 1,1

[x1] [y1] - 2,2

[x2] [y2] - 5,5

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

enter image description here

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

enter image description here

现在,我有一个2D数组:

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个点,那么它将检测到任何点和任何点)...你注意到这开始看起来像寄宿生一个广场?

enter image description here

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

这似乎基本上是一个集群问题,而这些问题通常都很难。聚类的一部分原因很难说可能存在多个适用的映射。

例如(请原谅我糟糕的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.0001x + 1,y = 1,y = 0.0001x + 1}非常相似,行组{y = -10000x + 10,x = 0,y = 10000x - 10}也是非常相似,但cos(2θ)应尽可能远离它们,因为每组之间的任何两对应该几乎垂直。

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

我想,也许,两条线之间可能存在一些可用的“距离”度量,我只是不确定它会是什么。几乎平行的两条线在屏幕上汇聚(点通常在哪里)可能应该被认为比它们从屏幕上收集一万亿单位更“接近” - 或者它们应该?纯粹地说,如果没有一条线是平行的,那么三条线就不能成对地认为彼此更接近(如果它们在一个平面上,它们都会在某处相遇),但直观地说,如果我们有两条线通常是一英寸除了我们所关注的区域之外,我们选择的那对距离在两条相同的尖线之间,距离相关区域一英里。这让我觉得可能是之间的区域,由我们的区域*绑定*应该用作指标。

对不起,我不确定所有头脑风暴可能有多大用处,但它可能会对事情有所不同。

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

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

编辑II&amp; III:

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

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

(实际上,为了确定尺寸,我认为你甚至不需要测试你是否有3个共线点...我认为你只需要测试看你已经做了两个转弯......最少需要4分,但如果你运气不好则可能更多。其中两个点必须可以确定与另外两个不同的墙,这意味着真的很大反弹!)

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