Android,如何检查两个旋转视图之间的碰撞
Android, How to check collision between two rotated views
我正在尝试随机化框架视图中一些文本视图的位置。文本视图还将在 0 到 360 度之间随机旋转。 textViews 不允许彼此重叠,这意味着我需要检查碰撞(或者至少知道哪些点是 valid/not 有效)。我不知道如何在旋转时检查两个文本视图之间的碰撞。我曾尝试使用 Rect 相交,但这实际上不起作用,因为此功能仅在视图没有旋转时才有效。
这是我想要的示例:
TEXT1 放在第一位。当放置 TEXT2 时,TEXT1 和 TEXT2 周围的绿色边框发生碰撞,这意味着不应允许将 TEXT2 放置在那里。然而,TEXT3 不会与任何东西发生碰撞,应该允许放置。所以我想检查绿色边框而不是蓝色矩形的碰撞。我该怎么做?
编辑
要旋转我正在使用的视图 View.setRotation(float)
我使用 setX(float) 和 setY(float) 定位文本视图。
我最终得到了以下解决方案,我在其中创建了 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]);
}
当我有两个区域现在具有与两个 textView 相同的位置和旋转时,我可以使用以下代码检查碰撞:
if (!region1.quickReject(region2) && region1.op(region2, Region.Op.INTERSECT)) {
return true; //There is a collision
}
可能不是最好的解决方案,但它完成了工作。
我正在尝试随机化框架视图中一些文本视图的位置。文本视图还将在 0 到 360 度之间随机旋转。 textViews 不允许彼此重叠,这意味着我需要检查碰撞(或者至少知道哪些点是 valid/not 有效)。我不知道如何在旋转时检查两个文本视图之间的碰撞。我曾尝试使用 Rect 相交,但这实际上不起作用,因为此功能仅在视图没有旋转时才有效。
这是我想要的示例:
TEXT1 放在第一位。当放置 TEXT2 时,TEXT1 和 TEXT2 周围的绿色边框发生碰撞,这意味着不应允许将 TEXT2 放置在那里。然而,TEXT3 不会与任何东西发生碰撞,应该允许放置。所以我想检查绿色边框而不是蓝色矩形的碰撞。我该怎么做?
编辑
要旋转我正在使用的视图 View.setRotation(float)
我使用 setX(float) 和 setY(float) 定位文本视图。
我最终得到了以下解决方案,我在其中创建了 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]);
}
当我有两个区域现在具有与两个 textView 相同的位置和旋转时,我可以使用以下代码检查碰撞:
if (!region1.quickReject(region2) && region1.op(region2, Region.Op.INTERSECT)) {
return true; //There is a collision
}
可能不是最好的解决方案,但它完成了工作。