扫描 AABB 与 2D 中的线段

问题描述

近一个星期以来,我一直在尝试启动并运行扫掠碰撞检测,但我终其一生都无法让它发挥作用。我想尝试对线段移动 AABB,看看它是否以及何时发生碰撞。

Example image

下面有一个关于这个链接的答案: https://gamedev.stackexchange.com/questions/29479/swept-aabb-vs-line-segment-2d/30220#30220?newreg=95e000808fe74acdbd7a6b7d1d4b3a05

我已将其翻译成 Go,它将运行游戏服务器并需要此逻辑:

func SweepRectLine(rectX,rectY,rectW,rectH,rectHSpeed,rectVSpeed,lineX1,lineY1,lineX2,lineY2 float64) (bool,float64) {
    outVel := [2]float64{}
    // hitNormal := [2]float64{}
    lineNX,lineNY := lineX2-lineX1,lineY2-lineY1
    // lineMinX,lineMaxX,lineMinY,lineMaxY := math.Min(lineX1,lineX2),math.Max(lineX1,math.Min(lineY1,lineY2),math.Max(lineY1,lineY2)
    var lineMinX,lineMaxY float64
    if lineNX > 0 {
        lineMinX,lineMaxX = lineX1,lineX2
    } else {
        lineMinX,lineMaxX = lineX2,lineX1
    }
    if lineNY > 0 {
        lineMinY,lineMaxY = lineY1,lineY2
    } else {
        lineMinY,lineMaxY = lineY2,lineY1
    }
    r := (rectW/2)*math.Abs(lineNX) + (rectH/2)*math.Abs(lineNY) //radius to Line
    boxProj := (lineX1-rectX)*lineNX + (lineY1-rectY)*lineNY
    velProj := rectHSpeed*lineNX + rectVSpeed*lineNY

    if velProj < 0 {
        r *= -1
    }

    hitTime := math.Max((boxProj-r)/velProj,0)
    outTime := math.Min((boxProj+r)/velProj,1)
    // log.Println("start",hitTime,outTime)

    rectXMax,rectXMin := rectX+rectW/2,rectX-rectW/2
    if rectHSpeed < 0 { // left
        if rectXMax < lineMinX {
            return false,0
        }
        hitTime = math.Max((lineMaxX-rectXMin)/rectHSpeed,hitTime)
        outTime = math.Min((lineMinX-rectXMax)/rectHSpeed,outTime)
    } else if rectHSpeed > 0 { // right
        if rectXMin > lineMaxX {
            return false,0
        }
        hitTime = math.Max((lineMinX-rectXMax)/rectHSpeed,hitTime)
        outTime = math.Min((lineMaxX-rectXMin)/rectHSpeed,outTime)
        // log.Println("right",outTime)
    } else {
        if lineMinX > rectXMax || lineMaxX < rectXMin {
            return false,0
        }
    }

    if hitTime > outTime {
        return false,0
    }

    rectYMax,rectYMin := rectY+rectH/2,rectY-rectH/2
    if rectVSpeed < 0 { // up
        if rectYMax < lineMinY {
            return false,0
        }
        hitTime = math.Max((lineMaxY-rectYMin)/rectVSpeed,hitTime)
        outTime = math.Min((lineMinY-rectYMax)/rectVSpeed,outTime)
    } else if rectVSpeed > 0 { // down
        if rectYMin > lineMaxY {
            return false,0
        }
        hitTime = math.Max((lineMinY-rectYMax)/rectVSpeed,hitTime)
        outTime = math.Min((lineMaxY-rectYMin)/rectVSpeed,outTime)
    } else {
        if lineMinY > rectYMax || lineMaxY < rectYMin {
            return false,0
    }

    outVel[0] = rectHSpeed * hitTime
    outVel[1] = rectVSpeed * hitTime
    return true,hitTime
}

我还在此处提供了一个带有可执行 UI 的 Gist:https://gist.github.com/KidLinus/3f847c46b0e6dc1addac7252d9cb54ab

我一生都无法弄清楚所有类变量代表什么。我认为其中一些是 Unity 原生的,但这只是猜测。我已经弄清楚了该范围是所述方向上宽度/高度的一半。 “line.n”代表什么是任何人的猜测,我假设它的方向并且不知道它是否被标准化。还有一些死变量就在那里。

我很乐意帮助您完成 Go 中的实现。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...