love.math.newTransform

Available since LÖVE 11.0
This function is not supported in earlier versions.

Creates a new Transform object.

Function

Creates a Transform with no transformations applied. Call methods on the returned object to apply transformations.

Synopsis

transform = love.math.newTransform( )

Arguments

None.

Returns

Transform transform
The new Transform object.

Function

Creates a Transform with the specified transformation applied on creation.

Synopsis

transform = love.math.newTransform( x, y, angle, sx, sy, ox, oy, kx, ky )

Arguments

number x
The position of the new Transform on the x-axis.
number y
The position of the new Transform on the y-axis.
number angle (0)
The orientation of the new Transform in radians.
number sx (1)
Scale factor on the x-axis.
number sy (sx)
Scale factor on the y-axis.
number ox (0)
Origin offset on the x-axis.
number oy (0)
Origin offset on the y-axis.
number kx (0)
Shearing / skew factor on the x-axis.
number ky (0)
Shearing / skew factor on the y-axis.

Returns

Transform transform
The new Transform object.

Examples

Creates a new Transform object and uses it to position and rotate a rectangle around its center:

function love.load()
    rectwidth = 100
    rectheight = 100

    -- arguments are: x, y, angle, scalex, scaley, offsetx, offsety
    transform = love.math.newTransform(100, 100, math.pi/4, 1, 1, rectwidth / 2, rectheight / 2)
end

function love.draw()
    love.graphics.applyTransform(transform)
    love.graphics.rectangle("fill", 0, 0, rectwidth, rectheight)
end


Creates two rectangles and rotates it around its center:

local function createTransform(rect)
	local transform = love.math.newTransform()
	transform:translate(rect.x + rect.width/2, rect.y + rect.height/2)
	transform:rotate(rect.rotation)
	return transform
end

function love.load()
	rect1 = {x=100, y=100, width=200, height=200, rotation=1}
	rect1.transform = createTransform(rect1)
	rect2 = {x=300, y=100, width=200, height=100, rotation=0.1}
	rect2.transform = createTransform(rect2)
end

function love.draw()
	for i, rectangle in ipairs ({rect1, rect2}) do
		love.graphics.push()
			love.graphics.applyTransform(rectangle.transform)
			love.graphics.rectangle("line", -rectangle.width/2, -rectangle.height/2, rectangle.width, rectangle.height)
		love.graphics.pop()
		-- the line shows the middle of the rectangle:
		love.graphics.line (0, 0, rectangle.x+rectangle.width/2, rectangle.y+rectangle.height/2)
	end
end

Showing the pressed mouse position in the rescaled window:

local render_width, render_height = 800, 600
local renderClickX, renderClickY = nil, nil
local transform = love.math.newTransform()

function love.load()
	love.window.setMode(1920, 1080, {resizable=true})  -- initial size of the window
	love.resize(1920, 1080)
end

function love.resize(window_width, window_height)
	local scaleX = window_width / render_width
	local scaleY = window_height / render_height
	local scale = math.min(scaleX, scaleY)

	-- calculate the position to center the rectangle
	local rectX = (window_width - render_width * scale) / 2
	local rectY = (window_height - render_height * scale) / 2

	-- reset and apply scaling and translation to the transform
	transform = love.math.newTransform()
	transform:translate(rectX, rectY)  -- move the rectangle to the center
	transform:scale(scale, scale)  -- scale to fit the window
end

function love.mousepressed(x, y, button, istouch, presses)
	renderClickX, renderClickY = transform:inverseTransformPoint(x, y)
	renderClickX, renderClickY = math.floor(renderClickX+0.5), math.floor(renderClickY+0.5)
end

function love.draw()
	local mx, my = love.mouse.getPosition () -- top left is 0x0
	local rx, ry = transform:inverseTransformPoint(mx, my) -- rendered
	rx, ry = math.floor (rx+0.5), math.floor (ry+0.5)

	-- push the current transformation matrix
	love.graphics.push()

	-- apply the custom transform
	love.graphics.applyTransform(transform)

	-- set the color to red for the rectangle with diagonals
	love.graphics.setColor(1, 0, 0)
	love.graphics.rectangle("line", 0, 0, render_width, render_height)
	love.graphics.line(0, 0, render_width, render_height)
	love.graphics.line(render_width, 0, 0, render_height)

	-- mouse position as green lines crossing:
	love.graphics.setColor(0, 1, 0)
	love.graphics.line(0, ry, render_width, ry)
	love.graphics.line(rx, 0, rx, render_height)
	if renderClickX and renderClickY then
		-- clicked green circle:
		love.graphics.circle('line', renderClickX, renderClickY, 15)
		love.graphics.print("Click coordinates: (" .. renderClickX .. ", " .. renderClickY .. ")", renderClickX + 10, renderClickY + 10)
	end

	-- pop the transformation matrix to revert to previous state
	love.graphics.pop()

	-- display debug information
	love.graphics.setColor(1, 1, 1)
	love.graphics.print("Window size: " .. love.graphics.getWidth() 
		.. "x" .. love.graphics.getHeight(), 10, 10)
	love.graphics.print("Render size: " .. render_width .. "x" .. render_height, 10, 30)
	love.graphics.print("Mouse window position: " .. mx .. "x" .. my, 10, 50)
	love.graphics.print("Mouse render position: " .. rx .. "x" .. ry, 10, 70)
end

See Also

Other Languages