2015-11-09 46 views
1

我想随机化一个frameview内的几个textviews的位置。 textviews也将有一个0到360度之间的随机旋转。 textViews不允许在彼此之间,这意味着我需要检查碰撞(或者至少知道哪些点是有效的/无效的)。旋转时,我不知道如何检查两个文本视图之间的碰撞。我试图使用矩形相交,但这并不真正的工作,因为这个功能只适用于没有旋转的视图。Android,如何检查两个旋转视图之间的碰撞

这里是我想要的一个例子:

enter image description here

TEXT1首先被放置。当放置TEXT2时,TEXT1和TEXT2周围的绿色边框发生碰撞,这意味着不应该允许TEXT2放置在那里。然而,TEXT3不会与任何事物相冲突,应该被允许放置。所以我想检查碰撞的绿色边框,而不是蓝色的矩形。我该怎么做呢?

编辑

要旋转我使用View.setRotation(float)

为了定位我使用setX的(浮点)和SETY(浮点)TextView的视图。

+0

你如何旋转这些视图?你能告诉我们代码吗? – dkarmazi

+0

我不知道你是如何旋转'视图'的,但如果你知道它们的坐标之前,你知道角度,你可以使用一些三角函数来计算边界框。这里是一个优秀的帖子:http://stackoverflow.com/questions/5789239/calculate-largest-rectangle-in-a-rotated-rectangle – jammaster

+0

要旋转textview我使用setRotation函数。 Se编辑 – FewWords

回答

0

我结束了以下解决方案,我创建了4个点,其中一个用于textView的每个角,然后以与textView相同的角度旋转。有了这些观点,我就可以创建一个我用来创建区域的路径。

private Region createRotatedRegion(TextView textView){ 
    Matrix matrix = new Matrix(); 
    matrix.setRotate(textView.getRotation(), textView.getX() + textView.getMeasuredWidth()/2, textView.getY() + textView.getMeasuredHeight()/2); 

    Path path = new Path(); 
    Point LT = rotatePoint(matrix, textView.getX(), textView.getY()); 
    Point RT = rotatePoint(matrix, textView.getX() + textView.getMeasuredWidth(), textView.getY()); 
    Point RB = rotatePoint(matrix, textView.getX() + textView.getMeasuredWidth(), textView.getY() + textView.getMeasuredHeight()); 
    Point LB = rotatePoint(matrix, textView.getX(), textView.getY() + textView.getMeasuredHeight()); 

    path.moveTo(LT.x, LT.y); 
    path.lineTo(RT.x, RT.y); 
    path.lineTo(RB.x, RB.y); 
    path.lineTo(LB.x, LB.y); 

    Region region = new Region(); 
    region.setPath(path, new Region(0, 0, textViewParent.getWidth(), textViewParent.getHeight())); 
    return region; 
} 

private Point rotatePoint(Matrix matrix, float x, float y){ 
    float[] pts = new float[2]; 
    pts[0] = x; 
    pts[1] = y; 
    matrix.mapPoints(pts); 
    return new Point((int)pts[0], (int)pts[1]); 
} 

当我有现在具有相同的位置和旋转两个textViews然后我就可以使用下面的代码来检查碰撞两个区域:

if (!region1.quickReject(region2) && region1.op(region2, Region.Op.INTERSECT)) { 
    return true; //There is a collision 
} 

可能不是最好的解决方案,但它得到工作完成。