2015-11-09 47 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 
} 

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