diff --git a/docs/MainModule.rst b/docs/MainModule.rst index 61ff506..fad8b07 100644 --- a/docs/MainModule.rst +++ b/docs/MainModule.rst @@ -254,6 +254,25 @@ You can iterate over the shapes using ``pairs`` (see example). game.selectUnit(s) end +.. function:: HC.raycast(x, y, dx, dy, range) + + :param numbers x,y: Origin point of ray + :param numbers dx,dy: Direction vector of ray(normal vector) + :param number range: Range of raycast + :returns: Table of shapes that got hit and its hit points. + +Gets shapes that got hit by a given ray and the points which that shape intersects with the ray. +The table is a *set*, meaning that the shapes are stored in *keys* of the table. The values are the points of intersection. You can iterate over the shapes using ``pairs`` (see example). + +**Example**:: + + local hits = HC.raycast(originx, originy, directionx, directiony, range) + for shape, points in pairs(hits) do + for _, point in ipairs(points) do + love.graphics.points(point.x, point.y) + end + end + .. function:: HC.hash() diff --git a/init.lua b/init.lua index 8ec9481..0fa3999 100644 --- a/init.lua +++ b/init.lua @@ -118,6 +118,30 @@ function HC:collisions(shape) return candidates end +function HC:raycast(x, y, dx, dy, range) + local dxr, dyr = dx * range, dy * range + local bbox = { x + dxr , y + dyr, x, y } + local candidates = self._hash:inSameCells(unpack(bbox)) + + for col in pairs(candidates) do + local rparams = col:intersectionsWithRay(x, y, dx, dy) + if #rparams > 0 then + for i, rparam in pairs(rparams) do + if rparam < 0 or rparam > range then + rawset(rparams, i, nil) + else + local hitx, hity = x + (rparam * dx), y + (rparam * dy) + rawset(rparams, i, { x = hitx, y = hity }) + end + end + rawset(candidates, col, rparams) + else + rawset(candidates, col, nil) + end + end + return candidates +end + function HC:shapesAt(x, y) local candidates = {} for c in pairs(self._hash:cellAt(x, y)) do