12

私は解決策を見つけましたが、私のロジックが最も効率的であることを確認したいと思いました。もっと良い方法があると思います。左下隅の(x、y)座標、2つの長方形の高さと幅があり、それらの交点である3番目の長方形を返す必要があります。不正行為をしていると感じたので、コードを投稿したくありません。

  1. グラフの一番左と一番上にあるものを見つけます。
  2. 一方が他方と完全に重なっているかどうかを確認し、もう一方がX軸の最初の部分と完全に重なっているかどうかを確認します。
  3. X軸の部分的な交差をチェックします。
  4. 基本的に、Y軸に対して手順2と3を繰り返します。
  5. 私はいくつかの計算を行い、それらの条件に基づいて長方形のポイントを取得します。

私はこれを考えすぎて、非効率的なコードを書いているかもしれません。私はすでに実用的なプログラムを提出しましたが、自分の知識のための最良の方法を見つけたいと思っています。誰かが同意するか、私を正しい方向に向けることができれば、それは素晴らしいことです!

4

3 に答える 3

20

JDK API を使用してこれを行ってみませんか?

Rectangle rect1 = new Rectangle(100, 100, 200, 240);
Rectangle rect2 = new Rectangle(120, 80, 80, 120);
Rectangle intersection = rect1.intersection(rect2);

クラスを使用する場合java.awt.Rectangle、コンストラクターのパラメーターは x、y、幅、高さです。x、y は四角形の左上隅です。左下のポイントを左上に簡単に変換できます。


上記をお勧めしますが、本当に自分でやりたい場合は、次の手順に従ってください。

たとえば(x1, y1), (x2, y2)、Rect1 の左下と右下の角はそれぞれ、Rect2 の角です (x3, y3), (x4, y4)

  • の大きい方x1x3の小さい方x2x4たとえばxLxRそれぞれ 見つけます。
    • の場合xL >= xR、交差点を返さない
  • の大きい方y1y3の小さい方y2y4たとえばyTyBそれぞれ 見つけます。
    • の場合yT >= yB、交差点を返さない
    • 戻り(xL, yB, xR-xL, yB-yT)ます。

より Java に似た擬似コード:

// Two rectangles, assume the class name is `Rect`
Rect r1 = new Rect(x1, y2, w1, h1);
Rect r2 = new Rect(x3, y4, w2, h2);

// get the coordinates of other points needed later:
int x2 = x1 + w1;
int x4 = x3 + w2;
int y1 = y2 - h1;
int y3 = y4 - h2;

// find intersection:
int xL = Math.max(x1, x3);
int xR = Math.min(x2, x4);
if (xR <= xL)
    return null;
else {
    int yT = Math.max(y1, y3);
    int yB = Math.min(y2, y4);
    if (yB <= yT)
        return null;
    else
        return new Rect(xL, yB, xR-xL, yB-yT);
}

ご覧のとおり、長方形が元々 2 つの対角線の角で定義されていた場合は、簡単になります。その部分を実行するだけで済みます// find intersection

于 2013-01-31T02:00:20.697 に答える
13

小さな効用関数で 2 つの長方形の交点を決定する私のバリエーション。

//returns true when intersection is found, false otherwise.
//when returning true, rectangle 'out' holds the intersection of r1 and r2.
private static boolean intersection2(Rectangle r1, Rectangle r2,
        Rectangle out) {
    float xmin = Math.max(r1.x, r2.x);
    float xmax1 = r1.x + r1.width;
    float xmax2 = r2.x + r2.width;
    float xmax = Math.min(xmax1, xmax2);
    if (xmax > xmin) {
        float ymin = Math.max(r1.y, r2.y);
        float ymax1 = r1.y + r1.height;
        float ymax2 = r2.y + r2.height;
        float ymax = Math.min(ymax1, ymax2);
        if (ymax > ymin) {
            out.x = xmin;
            out.y = ymin;
            out.width = xmax - xmin;
            out.height = ymax - ymin;
            return true;
        }
    }
    return false;
}
于 2013-10-24T16:49:13.603 に答える
5

Rectangle ソース コードを使用して、独自のアルゴリズムと比較することもできます。

/**
 * Computes the intersection of this <code>Rectangle</code> with the
 * specified <code>Rectangle</code>. Returns a new <code>Rectangle</code>
 * that represents the intersection of the two rectangles.
 * If the two rectangles do not intersect, the result will be
 * an empty rectangle.
 *
 * @param     r   the specified <code>Rectangle</code>
 * @return    the largest <code>Rectangle</code> contained in both the
 *            specified <code>Rectangle</code> and in
 *            this <code>Rectangle</code>; or if the rectangles
 *            do not intersect, an empty rectangle.
 */
public Rectangle intersection(Rectangle r) {
    int tx1 = this.x;
    int ty1 = this.y;
    int rx1 = r.x;
    int ry1 = r.y;
    long tx2 = tx1; tx2 += this.width;
    long ty2 = ty1; ty2 += this.height;
    long rx2 = rx1; rx2 += r.width;
    long ry2 = ry1; ry2 += r.height;
    if (tx1 < rx1) tx1 = rx1;
    if (ty1 < ry1) ty1 = ry1;
    if (tx2 > rx2) tx2 = rx2;
    if (ty2 > ry2) ty2 = ry2;
    tx2 -= tx1;
    ty2 -= ty1;
    // tx2,ty2 will never overflow (they will never be
    // larger than the smallest of the two source w,h)
    // they might underflow, though...
    if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
    if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
    return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
}
于 2016-04-02T10:02:04.383 に答える