Shape:rayCast
Available since LÖVE 0.8.0
This function is not supported in earlier versions.
Casts a ray against the shape and returns the surface normal vector and the line position where the ray hit. If the ray missed the shape, nil will be returned. The Shape can be transformed to get it into the desired position.
The ray starts on the first point of the input line and goes towards the second point of the line. The fourth argument is the maximum distance the ray is going to travel as a scale factor of the input line length.
The childIndex parameter is used to specify which child of a parent shape, such as a ChainShape, will be ray casted. For ChainShapes, the index of 1 is the first edge on the chain. Ray casting a parent shape will only test the child specified so if you want to test every shape of the parent, you must loop through all of its children.
The world position of the impact can be calculated by multiplying the line vector with the third return value and adding it to the line starting point.
hitx, hity = x1 + (x2 - x1) * fraction, y1 + (y2 - y1) * fraction
There is a bug in 0.8.0 where the normal vector returned by this function gets scaled by love.physics.getMeter.
Function
Synopsis
xn, yn, fraction = Shape:rayCast( x1, y1, x2, y2, maxFraction, tx, ty, tr, childIndex )
Arguments
number x1
- The x position of the input line starting point.
number y1
- The y position of the input line starting point.
number x2
- The x position of the input line end point.
number y2
- The y position of the input line end point.
number maxFraction
- Ray length parameter.
number tx
- The translation of the shape on the x-axis.
number ty
- The translation of the shape on the y-axis.
number tr
- The shape rotation.
number childIndex (1)
- The index of the child the ray gets cast against.
Returns
number xn
- The x component of the normal vector of the edge where the ray hit the shape.
number yn
- The y component of the normal vector of the edge where the ray hit the shape.
number fraction
- The position on the input line where the intersection happened as a factor of the line length.
Examples
Casting 2 different rays against a box.
function love.load() -- Setting this to 1 to avoid all current scaling bugs. love.physics.setMeter(1) Box = {} Box.x, Box.y, Box.r = 400, 300, 3.3 Box.Shape = love.physics.newRectangleShape(150, 150) Ray1 = { point1 = {}, point2 = {}, } Ray1.point1.x, Ray1.point1.y = 50, 50 Ray1.point2.x, Ray1.point2.y = 400, 300 Ray1.scale = 1 Ray2 = { point1 = {}, point2 = {}, } Ray2.point1.x, Ray2.point1.y = 500, 400 Ray2.point2.x, Ray2.point2.y = Ray2.point1.x + math.cos(math.pi*1.45), Ray2.point1.y + math.sin(math.pi*1.45) Ray2.scale = 150 end function love.draw() -- Drawing the box. love.graphics.setColor(255, 255, 255) love.graphics.push() -- For great point rotation! love.graphics.translate(Box.x, Box.y) love.graphics.rotate(Box.r) love.graphics.polygon("line", Box.Shape:getPoints()) love.graphics.pop() -- Drawing the input lines of the rays and the reach of ray 2 in gray. love.graphics.setLineWidth(3) love.graphics.setColor(50, 50, 50) love.graphics.line(Ray2.point1.x, Ray2.point1.y, Ray2.point1.x + (Ray2.point2.x - Ray2.point1.x) * Ray2.scale, Ray2.point1.y + (Ray2.point2.y - Ray2.point1.y) * Ray2.scale) love.graphics.setColor(255, 255, 255) love.graphics.line(Ray1.point1.x, Ray1.point1.y, Ray1.point2.x, Ray1.point2.y) love.graphics.line(Ray2.point1.x, Ray2.point1.y, Ray2.point2.x, Ray2.point2.y) love.graphics.setLineWidth(1) -- Remember that the ray cast can return nil if it hits nothing. local r1nx, r1ny, r1f = Box.Shape:rayCast(Ray1.point1.x, Ray1.point1.y, Ray1.point2.x, Ray1.point2.y, Ray1.scale, Box.x, Box.y, Box.r) local r2nx, r2ny, r2f = Box.Shape:rayCast(Ray2.point1.x, Ray2.point1.y, Ray2.point2.x, Ray2.point2.y, Ray2.scale, Box.x, Box.y, Box.r) if r1nx then -- Calculating the world position where the ray hit. local r1HitX = Ray1.point1.x + (Ray1.point2.x - Ray1.point1.x) * r1f local r1HitY = Ray1.point1.y + (Ray1.point2.y - Ray1.point1.y) * r1f -- Drawing the ray from the starting point to the position on the shape. love.graphics.setColor(255, 0, 0) love.graphics.line(Ray1.point1.x, Ray1.point1.y, r1HitX, r1HitY) -- We also get the surface normal of the edge the ray hit. Here drawn in green love.graphics.setColor(0, 255, 0) love.graphics.line(r1HitX, r1HitY, r1HitX + r1nx * 25, r1HitY + r1ny * 25) end if r2nx then -- Calculating the world position where the ray hit. local r2HitX = Ray2.point1.x + (Ray2.point2.x - Ray2.point1.x) * r2f local r2HitY = Ray2.point1.y + (Ray2.point2.y - Ray2.point1.y) * r2f -- Drawing the ray from the starting point to the position on the shape. love.graphics.setColor(255, 0, 0) love.graphics.line(Ray2.point1.x, Ray2.point1.y, r2HitX, r2HitY) -- We also get the surface normal of the edge the ray hit. Here drawn in green love.graphics.setColor(0, 255, 0) love.graphics.line(r2HitX, r2HitY, r2HitX + r2nx * 25, r2HitY + r2ny * 25) end end
Please login to continue.