2016-11-23 54 views
0

我有一个4个PointF对象的数组。此数组中的每个点都是矩形的一个角。现在我想根据它们的位置以特定的顺序在该数组中设置点。例如PointF[0]应为顶部点,PointF[1]为底部左侧(顺时针方向依此类推)。检测已知点在矩形中的位置

我试着检查坐标,例如如果点x和y坐标是阵列中每个点的最低点,则它是最低点(图像坐标系)。如果每个坐标都是最大的,那就是最重要的一点。

该解决方案的问题在于,有可能该阵列中的点也可以表示平行四边形或梯形含义,角之间的角度不必是90度。

这里一个形象,我试图想象我想达到的目标:

Example

+0

将点之间的界线看作格式为“y(x)= m * x + b''的多项式函数。 ''m''和''b''可以通过你的''PointF''的坐标来计算。这应该让你开始。 – f1sh

+0

我不知道我是否理解你是对的,但我认为你的意思是说,以'b'为例,我可以确定一个点是顶角还是右下角?而用'm'我可以确定它是左边还是右边,如果那是这样的话,如果这个点是右角,那么值是多少? –

回答

0

我找到了一个很好的解决方案,可以完美融入了我的问题。

首先,我尝试检测矩形的左上角和右下角。为此,我计算坐标系源的二维矢量的长度。 4个向量中最短的将是左上角和右下角最大的。另外两点我尝试通过简单的坐标检查与两个已知点进行检测。为了避免一个小错误,右上角将通过与左下角相同的检查,我通过它们的x坐标对点进行排序。

下面是代码:

private PointF[] checkPointLocation(PointF[] points){ 

    double minLength = 100000000; 
    double maxLength = 0; 
    int minPos = 0; 
    int maxPos = 0; 

    for(int i = 0; i < points.length; i++){ 
     double vLength = Math.abs(Math.sqrt((points[i].x * points[i].x) + (points[i].y * points[i].y))); 

     if(vLength < minLength) { 
      minLength = vLength; 
      minPos = i; 
     } 
     if(vLength > maxLength) { 
      maxLength = vLength; 
      maxPos = i; 
     } 
    } 

    PointF topLeft = points[minPos]; 
    PointF bottomRight = points[maxPos]; 

    Log.d(TAG, "TopLeft: " + topLeft); 
    Log.d(TAG, "BottomRight: " + bottomRight); 

    PointF topRight = null; 
    PointF bottomLeft = null; 

    Arrays.sort(points, (o1, o2) -> Float.compare(o1.x, o2.x)); 

    for(int i = 0; i < points.length; i++){ 
     PointF p = points[i]; 
     Log.d(TAG, "Point: " + p); 

     if(p.equals(topLeft) || p.equals(bottomRight)) 
      continue; 

     if(bottomLeft == null && p.x < bottomRight.x && p.y > topLeft.y) 
      bottomLeft = p; 

     if(topRight == null && p.x > topLeft.x && p.y < bottomRight.y) 
      topRight = p; 
    } 

    if(topRight == null){ 
     throw new NullPointerException("topRight is null"); 
    } 
    if(bottomLeft == null){ 
     throw new NullPointerException("BottomLeft is null"); 
    } 

    Log.d(TAG, "BottomLeft = " + bottomLeft); 
    Log.d(TAG, "TopRight = " + topRight); 

    PointF[] ccwPoints = {topLeft, bottomLeft, bottomRight, topRight}; 

    return ccwPoints; 
} 

对于我来说,这个解决方案是对所有可能的用户输入。