0
\$\begingroup\$

I've been trying to get a swept collision detection up and running now for almost a week and I can't for the life of me get it working.

Example image

There is a answer on this linked here below: Swept AABB vs Line Segment 2D

I've translated this into Go which will be running the game server and needs this logic:

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, lineX2), math.Min(lineY1, lineY2), math.Max(lineY1, lineY2)
 var lineMinX, lineMaxX, lineMinY, 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", hitTime, 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
 }
 }
 if hitTime > outTime {
 return false, 0
 }
 outVel[0] = rectHSpeed * hitTime
 outVel[1] = rectVSpeed * hitTime
 return true, hitTime
}

I also put up a Gist with a executable UI here: https://gist.github.com/KidLinus/3f847c46b0e6dc1addac7252d9cb54ab

I can't for the life of me figure out what all class variables stand for. I think that some of them are native to Unity but that's just a guess. I've come so far as to figure out that the extent is half of the width/height in said direction. What the "line.n" stands for is anyones guess, I assume its the direction and have no idea if it's normalized or not.

There are also a couple of dead variables just laying there.

asked May 4, 2021 at 7:35
\$\endgroup\$
5
  • \$\begingroup\$ Line.n looks like a unit normal to the line — a direction vector perpendicular to the line and 1 unit in length. Anything else you're having trouble with? \$\endgroup\$ Commented May 4, 2021 at 11:25
  • \$\begingroup\$ Well, to start off I don't know which of the normals :/ I've tried it as both normals but have no luck. The same wierd collisions still happends. \$\endgroup\$ Commented May 4, 2021 at 11:56
  • \$\begingroup\$ Might want to add that detail to your question then. \$\endgroup\$ Commented May 4, 2021 at 11:57
  • 1
    \$\begingroup\$ Please reduce your code to a mcve and include it in your question. Not only does it better follow the community guidelines (in that questions should be relatively self contained), but increases the number of people who will actually look at your code (as fewer users are going to click through & sift through your project). \$\endgroup\$ Commented May 4, 2021 at 14:09
  • \$\begingroup\$ My snippet is a single 160 line file with the minimal amount of boiler required to actually fire up it and view if it is working. \$\endgroup\$ Commented May 4, 2021 at 15:22

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.