Android,如何检查两个旋转视图之间的冲突

时间:2015-11-09 15:54:05

标签: android collision-detection

我试图在frameview中随机化几个textviews的位置。文本视图还将具有0到360度之间的随机旋转。 textViews不允许在彼此之上,这意味着我需要检查冲突(或至少知道哪些点有效/无效)。我不知道如何在旋转时检查两个文本视图之间的碰撞。我曾尝试使用Rect相交,但这不起作用,因为只有在视图没有旋转时此函数才有效。

以下是我想要的例子:

enter image description here

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

修改

要旋转视图,我正在使用View.setRotation(float)

要定位textview我正在使用setX(float)和setY(float)。

1 个答案:

答案 0 :(得分:0)

I ended up with the following solution where I create 4 points, one for each corner of the textView, which I then rotate at the same angle as the textView. With these points I then create a Path which I am using to create a region.

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]);
}

When I have two regions which now have the same position and rotation as two textViews I can then use the following code to check for collision:

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

Probably not the best solution but it gets the job done.