Difference between revisions of "love.math.newTransform"

(Created page)
 
(Examples)
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{newin|[[0.11.0]]|110|type=function}}
+
{{newin|[[11.0]]|110|type=function}}
 
Creates a new [[Transform]] object.
 
Creates a new [[Transform]] object.
  
Line 9: Line 9:
 
</source>
 
</source>
 
=== Arguments ===
 
=== Arguments ===
None
+
None.
 +
 
 
=== Returns ===
 
=== Returns ===
 
{{param|Transform|transform|The new Transform object.}}
 
{{param|Transform|transform|The new Transform object.}}
Line 33: Line 34:
  
 
== Examples ==
 
== Examples ==
Creates a new Transform object and uses it to position and rotate a rectangle around its center.
+
Creates a new Transform object and uses it to position and rotate a rectangle around its center:
 
<source lang="lua">
 
<source lang="lua">
 
function love.load()
 
function love.load()
Line 48: Line 49:
 
end
 
end
 
</source>
 
</source>
 +
 +
 +
Creates two rectangles and rotates it around its center:
 +
<source lang="lua">
 +
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
 +
</source>
 +
 +
Showing the pressed mouse position in the rescaled window:
 +
 +
<source lang="lua">
 +
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
 +
 +
</source>
 +
 
== See Also ==
 
== See Also ==
 
* [[parent::love.math]]
 
* [[parent::love.math]]

Latest revision as of 16:08, 26 February 2025

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