1

2 つの線の交点を計算する関数を必要とする小さなゲームに取り組んでいます。そこで、ウィキペディア ( http://en.wikipedia.org/wiki/Line-line_intersection ) からこの式を取得し、関数にしました。

bool lineline(int L1X1, int L1Y1, int L1X2, int L1Y2, int L2X1, int L2Y1, int L2X2, int L2Y2, int* X, int* Y) { // Returns the point of intersection of two lines
    int D = (L1X1 - L1X2) * (L2Y1 - L2Y2) - (L1Y1 - L1Y2) * (L2X1 - L2X2); // Denominator. If zero then no intersection

    if (D == 0) { // Parallel and possibly overlapping
        return false;
    } else {
        *X = ( (L1X1 * L1Y2 - L1Y1 * L1X2) * (L2X1 - L2X2) - (L1X1 - L1X2) * (L2X1 * L2Y2 - L2Y1 * L2X2) ) / D; // Calculate x
        *Y = ( (L1X1 * L1Y2 - L1Y1 * L1X2) * (L2Y1 - L2Y2) - (L1Y1 - L1Y2) * (L2X1 * L2Y2 - L2Y1 * L2X2) ) / D; // Calculate y

        std::cout << D << " | " << *X << " | " << *Y << "\n";

        if (*X >= Bmin(L1X1, L1X2) && *X <= Bmax(L1X1, L1X2) && *Y >= Bmin(L1Y1, L1Y2) && *Y <= Bmax(L1Y1, L1Y2)) {
            // Intersection is on first line
            if (*X >= Bmin(L2X1, L2X2) && *X <= Bmax(L2X1, L2X2) && *Y >= Bmin(L2Y1, L2Y2) && *Y <= Bmax(L2Y1, L2Y2)) {
                // Intersection is on second line
                return true;
            } else {
                // Intersection is on first, but not on second line
                return false;
            }
        } else {
            // Intersection is not on first line.
            return false;
        }

        return true;
    }
}

たとえば、これらの引数で呼び出すと、trueが返されます

lineline(400, 0, 400, 2000, 0, 400, 2000, 400, &x, &y);

しかし、2行目を1300台上に移動すると…

lineline(400, 0, 400, 2000, 0, 1700, 2000, 1700, &x, &y) == false;

false を返します。2 番目の関数呼び出しからの 2 つの行は交差するはずですが、そうですか? これらのパラメータで計算される値は次のとおりです。

D = -4000000
*X = 400;
*Y = -447;

誰でもこれで私を助けることができますか? 私はこれで1日立ち往生しており、前回と同じように単純なものが欠けているだけかもしれませんが、それを見ることができません. 前もって感謝します!

4

2 に答える 2

3

この式は、入力数値の差を 3 度まで上げます。そのため、差がおよそ 3 桁の場合、int9 桁の をオーバーフローしないように注意する必要があります。さらに、最初の桁が 2 になる可能性があります。int、正の数を掛けた結果として負の数が表示されるようになるため、残りの計算が正しくなくなります。

long long範囲を改善するには、中間結果に64 ビット整数 (つまり ) を使用します。

于 2013-03-02T08:56:11.807 に答える
0

100%確実ではありませんが、値を再スケーリングできませんか?たとえば、すべてを最大で分割し、フロートの結果を使用すると、同じサイズが単純に異なる比率になります。正確なクロスポイントは必要ないので、これは機能するはずです。平行線では0が得られないことを覚えておいてください。したがって、D値を定義する範囲0 +/- alphaを定義するには、非常に小さい値alphaを使用する必要があります。平行線。

于 2013-03-02T09:11:19.753 に答える