--多边形与圆形碰撞 function PolygonToCircle(polygon,circlePos,radius) local vectorNum = polygon:VectorNumber(); local next = 0 for current = 0 , vectorNum do if (current == vectorNum - 1) then next = 0 else next = current + 1 end local vc = polygon:GetVector(current) local vn = polygon:GetVector(next) --线是否与圆碰撞 if LineToCircle(vc,vn,circlePos,radius) then return true end end --多边形是否与圆点碰撞 PolygonToPoint(polygon,circlePos) end
--线与圆的碰撞 function LineToCircle(linePoint1,linePoint2,circlePos,radius) --这里需要分成两种情况,一种是线段两边的点是否在圆内 --如果点到半径的距离 if PointToCircle(linePoint1,circlePos,radius) then return true end if PointToCircle(linePoint2,circlePos,radius) then return true end --寻找圆心最近的点 local lineVec = {x= (linePoint2.x - linePoint1.x) , y = (linePoint2.y - linePoint1.y)} local pointToLinePoint1 = {x= (circlePos.x - linePoint1.x) , y = (circlePos.y - linePoint1.y)} local lineLength = math.sqrt(lineVec.x * lineVec.x + lineVec.y * lineVec.y) --点乘向量公式 相当于 lineLength * pointLinePoint1Length * cos角度 local dot = lineVec.x * pointToLinePoint1.x + lineVec.y * pointToLinePoint1.y --这里就是pointLinePoint1Length * cos角度 及为lineVec 的投影长度,温馨提示pointLinePoint1ToLine可能为正负值 取决于向量的夹角的cos值 --相当于到线段的投影比例 local pointLinePoint1ToLine = dot / lineLength local closestX = linePoint1.x + pointLinePoint1ToLine * (linePoint2.x - linePoint1.x) local closestY = linePoint1.y + pointLinePoint1ToLine * (linePoint2.y - linePoint1.y) local isInLine = PointToLine({ x = closestX,y = closestY} , linePoint1, linePoint2) --如果点不在线上面(就是相当于他是在延长线 ) 直接returnfalse if not isInLine then return false; end --点跟圆的碰撞 local result = PointToCircle({ x = closestX,y = closestY},circlePos,radius) return result end
--点与直线的碰撞 function PointToLine(point , linePoint1, linePoint2) --思想点与线两边线段的距离跟线的距离的判断,相等就是在同一直线 local line1 = math.sqrt((linePoint1.x - point.x) * (linePoint1.x - point.x) + (linePoint1.y - point.y)* (linePoint1.y - point.y)) local line2 = math.sqrt((linePoint2.x - point.x) * (linePoint2.x - point.x) + (linePoint2.y - point.y)* (linePoint2.y - point.y)) local line = math.sqrt((linePoint2.x - linePoint1.x) * (linePoint2.x - linePoint1.x) + (linePoint2.y - linePoint1.y)* (linePoint2.y - linePoint1.y)) return (line1 + line2) == line end
--圆跟圆是否碰撞 function CircleToCircle (circlePos1,radius1,circlePos2,radius2) local sqr2 = (circlePos1.x - circlePos2.x) * (circlePos1.x - circlePos2.x) + (circlePos1.y - circlePos2.y)*(circlePos1.y - circlePos2.y) return (radius1+radius2) * (radius1+radius2) >= sqr2 end
--多边形与点的碰撞 function PolygonToPoint(polygon,point) local vectorNum = polygon:VectorNumber(); local collision = false local next = 0 for current = 0 , vectorNum do if (current == vectorNum - 1) then next = 0 else next = current + 1 end local vc = polygon:GetVector(current) local vn = polygon:GetVector(next) if PointToLine(point,vc, vn) then return true end --若尔当曲线定理 需要的同学可以去学习一下 if (((vc.y >= py and vn.y < py) or (vc.y < py and vn.y >= py)) and (px < (vn.x - vc.x) * (py - vc.y) / (vn.y - vc.y) + vc.x)) then collision = not collision end end return collision end