5

線分L =ABを形成する2つのベクトルABが与えられます。さらに、左、右、下、上、近距離、遠距離の平面によって定義される錐台Fのビューが与えられます。

LをFに対してクリップするにはどうすればよいですか?

つまり、交差点テストし、 Lのどこでその交差点が発生するのでしょうか。(線分が角で2つの側面と交差する場合、錐台と複数の交差を持つ可能性があることに注意してください。

可能であれば、コード例を提供してください(C ++またはPythonを推奨)。

4

3 に答える 3

4

今はコードを書きたくありませんが、「フラスタム」を正しく理解していれば、次のように動作するはずです。

  1. 指定されたすべての平面と線を交差させます
  2. 交差点が 2 つある場合は、完了です。
  3. 交差が 1 つしかない場合は、前面を計算して交差させます。
  4. それでも交差が 1 つしかない場合は、バック プレーンを計算して交差させます。

しかし、私は完全に誤解していたかもしれません。その場合は、詳しく説明してください:)

于 2008-09-16T22:21:31.997 に答える
1

まず、ビュー マトリックスから平面を抽出します

次に、ポイントを使用してベクトルと最小/最大を (0, 1) として定義し、平面を反復処理してセグメントと交差させ、最小/最大を更新し、min > max.

これは純粋な Python 関数の例で、外部 deps はありません。

def clip_segment_v3_plane_n(p1, p2, planes):
    """
    - p1, p2: pair of 3d vectors defining a line segment.
    - planes: a sequence of (4 floats): `(x, y, z, d)`.

    Returns 2 vector triplets (the clipped segment)
    or (None, None) then segment is entirely outside.
    """
    dp = sub_v3v3(p2, p1)

    p1_fac = 0.0
    p2_fac = 1.0

    for p in planes:
        div = dot_v3v3(p, dp)
        if div != 0.0:
            t = -plane_point_side_v3(p, p1)
            if div > 0.0:  # clip p1 lower bounds
                if t >= div:
                    return None, None
                if t > 0.0:
                    fac = (t / div)
                    if fac > p1_fac:
                        p1_fac = fac
                        if p1_fac > p2_fac:
                            return None, None
            elif div < 0.0:  # clip p2 upper bounds
                if t > 0.0:
                    return None, None
                if t > div:
                    fac = (t / div)
                    if fac < p2_fac:
                        p2_fac = fac
                        if p1_fac > p2_fac:
                            return None, None

    p1_clip = add_v3v3(p1, mul_v3_fl(dp, p1_fac))
    p2_clip = add_v3v3(p1, mul_v3_fl(dp, p2_fac))

    return p1_clip, p2_clip


# inline math library
def add_v3v3(v0, v1):
    return (
        v0[0] + v1[0],
        v0[1] + v1[1],
        v0[2] + v1[2],
        )

def sub_v3v3(v0, v1):
    return (
        v0[0] - v1[0],
        v0[1] - v1[1],
        v0[2] - v1[2],
        )

def dot_v3v3(v0, v1):
    return (
        (v0[0] * v1[0]) +
        (v0[1] * v1[1]) +
        (v0[2] * v1[2])
        )

def mul_v3_fl(v0, f):
    return (
        v0[0] * f,
        v0[1] * f,
        v0[2] * f,
        )

def plane_point_side_v3(p, v):
    return dot_v3v3(p, v) + p[3]
于 2016-01-23T06:50:55.453 に答える
1

上で Touchy 伍長が言ったことに加えて、線分を平面と交差させる方法を知る必要があります。そのページの説明では、u はラインのパラメトリック定義のパラメーターを表します。最初に、説明した 2 つの方法のいずれかを使用して u を計算します。u の値が 0.0 から 1.0 の範囲内にある場合、平面は線分をセグメントのどこかでクリップします。線の方程式に u を再び差し込むと、その交点が発生するポイントが得られます。

もう 1 つの方法は、平面に対する各点の方向距離を見つけることです。一方の点の距離が正で、もう一方の点が負の場合、それらは平面の反対側にあります。次に、どの点が錐台の外側にあるかがわかります (平面の法線が指す方向に基づいて)。このアプローチを使用すると、有向距離の比率に基づいて線形補間を行うことで、交点をより迅速に見つけることができます。たとえば、1 つのポイントの距離が +12 で、もう 1 つのポイントが -12 の場合、平面がセグメントを半分に切断し、u パラメータが 0.5 であることがわかります。

お役に立てれば。

于 2008-09-18T07:17:40.607 に答える