0

いくつかの調査の結果、 2DゲームでLiang-Barskyラインクリッピングアルゴリズムを使用することにしました。Googleは、このアルゴリズムのVB.NET実装を提供していませんでしたが、C/++の実装はたくさん提供していました。したがって、私はC ++の知識があるので、 Skytopiaで見つかったものをVB.Netに移植することにしました。残念ながら、以下では機能しません。

Public Class PhysicsObject
    Public Function CollideRay(ByVal p0 As Point, ByVal p1 As Point, ByRef clip0 As Point, ByRef clip1 As Point) As Boolean
        Dim t0 As Double = 0.0
        Dim t1 As Double = 1.0
        Dim xdelta As Double = p1.X - p0.X
        Dim ydelta As Double = p1.Y - p0.Y
        Dim p, q, r As Double

        For edge = 0 To 3
            ' Traverse through left, right, bottom, top edges
            If (edge = 0) Then
                p = -xdelta
                q = -(AABB.Left - p0.X)
            ElseIf (edge = 1) Then
                p = xdelta
                q = (AABB.Right - p0.X)
            ElseIf (edge = 2) Then
                p = -ydelta
                q = -(AABB.Bottom - p0.Y)
            ElseIf (edge = 3) Then
                p = ydelta
                q = (AABB.Top - p0.Y)
            End If

            r = q / p

            If p = 0 And q < 0 Then Return False ' Don't draw line at all. (parallel line outside)

            If p < 0 Then
                If r > t1 Then
                    Return False ' Don't draw line at all.
                ElseIf r > t0 Then
                    t0 = r ' Line is clipped!
                End If
            ElseIf p > 0 Then
                If r < t0 Then
                    Return False ' Don't draw line at all.
                ElseIf r < t1 Then
                    t1 = r ' Line is clipped!
                End If
            End If
        Next

        clip0.X = p0.X + t0 * xdelta
        clip0.Y = p0.Y + t0 * ydelta
        clip1.X = p0.X + t1 * xdelta
        clip1.Y = p0.Y + t1 * ydelta

        Return True        ' (clipped) line is drawn
    End Function

    Public AABB As Rectangle
End Class

私は次のようなクラス/メソッドを使用しています:

    Dim testPhysics As PhysicsObject = New PhysicsObject
    testPhysics.AABB = New Rectangle(30, 30, 20, 20)

    Dim p0, p1 As Point
    p0 = New Point(0, 0)
    p1 = New Point(120, 120)

    Dim clip0, clip1 As Point
    clip0 = New Point(-1, -1)
    clip1 = New Point(-1, -1)

    GlobalRenderer.Graphics.DrawLine(Pens.LimeGreen, p0, p1)

    If testPhysics.CollideRay(p0, p1, clip0, clip1) Then
        GlobalRenderer.Graphics.DrawLine(Pens.Magenta, clip0, clip1)
    End If

ただし、CollideRayメソッドは3番目のエッジ反復(エッジ= 3)、r <t0で失敗するため、関数はfalseを返します。

私は元気で本当に困惑しているので、誰かが私のCollideRay関数の問題を見つけて、この動作を引き起こす可能性があるかどうか疑問に思っています。

前もって感謝します。

4

1 に答える 1

2

コードは異なる座標系を想定しています。リンクされたWebページではtopEdgeがbottomEdgeよりも大きいことに注意してください。テストは、BottomがTopよりも大きい通常のグラフィック座標で機能します。下の引数と上の引数を入れ替える必要があります。

于 2010-11-06T17:00:36.313 に答える