4

一連の x、y 座標点で定義された非直線があります。画面上でこれらの点の間に直接直線を引くことができましたが、問題はありませんでした。残念ながら、同じ長さのセグメントで線を引く必要があります。

これは、3 つの点を持つ非直線を複数の等距離点の配列に分割する必要がある方法の例です。(最後の赤い点は無視してください。これは、線が均等に分割されていない場合の結果であり、終点でもあります)

これは、3 つの点を持つ非直線を複数の等距離点の配列に分割する必要がある方法の例です。

「つなぎ目」の赤い線に注目してください。ベクトル AB と BC が角度を成す線 A->B->C があるとします。基本的に、線は点 B で曲がります。

点 A と点 B の間の線分を区切ることは、点までは問題ありません。しかし、AB がセグメントの長さで均等に分割されない場合、何か特別なことをする必要があります。残りの長さを三角形の 1 辺と見なす必要があります。一定のセグメント長は、BC セグメント (上の赤い線) に接続する三角形のもう 1 つの辺です。点 B からこの交点までの長さを知る必要があります。この情報を使用して、BC の線分の計算を続行できます。

これが私が解決しようとしている三角形です(以下、この図に表示されている変数を参照します) ここまでで、コサインの法則を使用して問題を分解しました。c 2 = a 2 + b 2 - 2ab * Cos( y )

問題は、私がすでに c を知っていることです。それはセグメントの長さです。a を解く必要があります (y を計算できます)。

私は多項式を書くところまで行きましたが、今は行き詰まっています: a 2 + b 2 - 2ab * Cos( y ) - c 2 = 0

または Ax 2 + Bx + C (A = 1、B = -2b * Cos( y )、C = b 2 - c 2、x = a)

これは正しいアプローチですか?次に何をすればいいですか?これを Actionscript で実装する必要があります。

編集:まあ、私は二次式を使用する必要があります。だから私は今得ます:

a = b * Cos( y ) +/- SqrRoot(c 2 - b 2 * Sin( y ) 2 )

これをどのようにコードに入れるか...

4

1 に答える 1

3

これが私がこれを解決した方法です。BとCはあなたが定義したものと同じです。私は、ポイントAを最初の行の最後の完全なセグメントの終わりと呼んでいます。(曲がる前の最後の点)中心がAで、半径=セグメントの長さの円を描く場合、その円が線分BCと交差する場所は、角を切るAからの線の端点(Dと呼びます)です。 。その点を見つけるために、私はきちんとしたヘルパー関数を見つけました。それほど長くはありません。簡単にするために、ここに貼り付けています。

/*---------------------------------------------------------------------------
Returns an Object with the following properties:
    enter           -Intersection Point entering the circle.
    exit            -Intersection Point exiting the circle.
    inside          -Boolean indicating if the points of the line are inside the circle.
    tangent     -Boolean indicating if line intersect at one point of the circle.
    intersects      -Boolean indicating if there is an intersection of the points and the circle.

If both "enter" and "exit" are null, or "intersects" == false, it indicates there is no intersection.

This is a customization of the intersectCircleLine Javascript function found here:

http://www.kevlindev.com/gui/index.htm

----------------------------------------------------------------------------*/
function lineIntersectCircle(A : Point, B : Point, C : Point, r : Number = 1):Object {
    var result : Object = new Object ();
    result.inside = false;
    result.tangent = false;
    result.intersects = false;
    result.enter=null;
    result.exit=null;
    var a : Number = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y);
    var b : Number = 2 * ((B.x - A.x) * (A.x - C.x) +(B.y - A.y) * (A.y - C.y));
    var cc : Number = C.x * C.x + C.y * C.y + A.x * A.x + A.y * A.y - 2 * (C.x * A.x + C.y * A.y) - r * r;
    var deter : Number = b * b - 4 * a * cc;
    if (deter <= 0 ) {
        result.inside = false;
    } else {
        var e : Number = Math.sqrt (deter);
        var u1 : Number = ( - b + e ) / (2 * a );
        var u2 : Number = ( - b - e ) / (2 * a );
        if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) {
            if ((u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1)) {
                result.inside = false;
            } else {
                result.inside = true;
            }
        } else {
            if (0 <= u2 && u2 <= 1) {
                result.enter=Point.interpolate (A, B, 1 - u2);
            }
            if (0 <= u1 && u1 <= 1) {
                result.exit=Point.interpolate (A, B, 1 - u1);
            }
            result.intersects = true;
            if (result.exit != null && result.enter != null && result.exit.equals (result.enter)) {
                result.tangent = true;
            }
        }
    }
    return result;
}

これは、いくつかのプロパティを持つオブジェクトを返す関数であるため、コードに実装するのは非常に簡単です。あなたはそれに3つのポイントと半径を渡す必要があります。最初の2つのポイントは、上記で定義したBとC、および最初に説明したポイントAです。ここでも、半径はセグメントの長さです。

//create an object
var myObject:Object = lineIntersectCircle(pointB, pointC, pointA, segmentLength);

それでおしまい!点Dの座標(上記を参照)は次のとおりです。(myObject.exit.x, myObject.exit.y)

于 2011-04-11T01:37:09.567 に答える