-- the following code is for generating a rotation table
local cos = math.cos
local sin = math.sin
local rad = math.rad
local sqrt = math.sqrt
local atan2 = math.atan2
local floor = math.floor
local ceil = math.ceil
local pi = math.pi
local abs = math.abs
local function rads(x,y)
local length = sqrt(x*x+y*y)
local angle = atan2(y,x)
return length, angle
end
local function degs(angle, length)
local x = length * cos(angle)
local y = length * sin(angle)
return x,y
end
local function rotatepoint(X,Y,x,y,rotangle)
local length, angle = rads(x-X, y-Y)
local newangle = angle + rotangle
local newx, newy = degs(newangle, length)
return newx+X, newy+Y
end
-- set X and Y coordinates about wich to rotate a texture. returns a table that contains all coordinates for angles 0-360
-- resolutin will set the resolution of angles should be bigger or equal to 0 (0 is no resolution and table might grow infinitly)
-- ULx, ULy, LLx, LLy, URx, URy, LRx, LRy is the initial transformation of the texture
function TB:getRotationTable(X, Y, resolution, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
local table = {}
local tablemt = {}
local resolution = resolution or 0
tablemt.__index = function(table, angle)
if resolution and (resolution > 0) then
angle = floor(angle/resolution+.5)*resolution
end
if angle >= 360 then
angle = angle - floor(angle/360)*360
elseif angle < 0 then
angle = angle + ceil((abs(angle)/360))*360
end
local test = rawget(table, angle)
if test then return test end
local radangle = rad(angle)
local subtable = {}
subtable.ULx, subtable.ULy = rotatepoint(X,Y,ULx,ULy,radangle)
subtable.LLx, subtable.LLy = rotatepoint(X,Y,LLx,LLy,radangle)
subtable.URx, subtable.URy = rotatepoint(X,Y,URx,URy,radangle)
subtable.LRx, subtable.LRy = rotatepoint(X,Y,LRx,LRy,radangle)
rawset(table, angle, subtable)
return subtable
end
setmetatable(table, tablemt)
return table
end

the goal of that code is to be able to rotate a pretransformed texture about any point and chaching the result in a table

the getRotationTable function returns a empty table with a sweet metafunction that will populate the table if you ask for a angle of rotation :)
so you can rotate the texture say to 180deg you simply access the table[180] and it will return table[180].ULx, table[180].ULy, table[180].LLx, table[180].LLy, table[180].URx, table[180].URy, table[180].LRx, table[180].LRy

then we simply plugin our result into the :SetTexCoord function which can be done like this

it will only store date between 0 and 360 if you access anything bigger or smaller the meta table will recalculate your input to be within the correct range and then either return cached data or calculate the data and cache it

the rotation is counterclockwise if you increase your angle

what is this meant for? basically its meant for textures that get rotated as an animation ingame but you can technically use it for fixed rotations to. be warned the table can grow to infinate size since it will also take decimal degrees like 1.2324235434655 and cache that result so if you are doing anymations try to stay with a cetrain set of angles and just use those :)

want to thank Wobin and Xinhuan about their insights about how texture transformations work (its kinda quirky imo)

any ideas on how to make this more efficent would be much appreciated

Edit: added a resolution arg which limits the table to multiples of that resolution should be a value between 0 and 360 :)

it will only store date between 0 and 360 if you access anything bigger or smaller the meta table will recalculate your input to be within the correct range and then either return cached data or calculate the data and cache it

That should be easily fixed if needed:

tablemt.__index = function(table, angle)
local normalizedAngle = angle
if angle >= 360 then
normalizedAngle = angle - floor(angle/360)*360
elseif angle < 0 then
normalizedAngle = angle + ceil((abs(angle)/360))*360
end
local subtable = rawget(table, normalizedAngle)
if not subtable then
local radangle = rad(normalizedAngle)
subtable = {}
subtable.ULx, subtable.ULy = rotatepoint(X,Y,ULx,ULy,radangle)
subtable.LLx, subtable.LLy = rotatepoint(X,Y,LLx,LLy,radangle)
subtable.URx, subtable.URy = rotatepoint(X,Y,URx,URy,radangle)
subtable.LRx, subtable.LRy = rotatepoint(X,Y,LRx,LRy,radangle)
table[normalizedAngle] = subtable
end
table[angle] = subtable
return subtable
end

bam i purposefully constrained the table between 0 and 360 cause there is no need to store anymore data if it was already calculated for the previous 360 degrees i can see people using the code to animate something that just keeps on spinning where the angle keeps increasing in that case your table would grow in size till you stop animating.

bam i purposefully constrained the table between 0 and 360 cause there is no need to store anymore data if it was already calculated for the previous 360 degrees i can see people using the code to animate something that just keeps on spinning where the angle keeps increasing in that case your table would grow in size till you stop animating.

Sounds reasonable. I only suggested it because you called it a "quirk". :P

so i was changing some code around and came across a dilemma

i am able to shrink memory usage to 69% but at the same time increase CPU usage 2.8 times

any ideas for what would be best? go for the smaller memory footprint or the faster calculations? (the change in cpu usage is only for calculating the new values at an unknown angle if you already know the angle the CPU usage is virtually 0 either way)

so i was changing some code around and came across a dilemma

i am able to shrink memory usage to 69% but at the same time increase CPU usage 2.8 times

any ideas for what would be best? go for the smaller memory footprint or the faster calculations? (the change in cpu usage is only for calculating the new values at an unknown angle if you already know the angle the CPU usage is virtually 0 either way)

Think about it this way. which is easier to upgrade, memory or cpu? so therefore which has higher priority? lower CPU usage should -always- trump memory.

Think about it this way. which is easier to upgrade, memory or cpu? so therefore which has higher priority? lower CPU usage should -always- trump memory.

except in this case, where results are cached, the speed penalty is only paid once -- so I would go with the reduced memory footprint.

should run with smaller memory footprint and faster calculations

it will now return a function instead of a table

-- the following code is for generating a rotation function
local cos = math.cos
local sin = math.sin
local rad = math.rad
local sqrt = math.sqrt
local atan2 = math.atan2
local floor = math.floor
local ceil = math.ceil
local pi = math.pi
local abs = math.abs
local function rotatepoint(X,Y,x,y,rotangle)
local xX = x-X
local yY = y-Y
local length = sqrt(xX*xX+yY*yY)
local angle = atan2(y-Y,xX) + rotangle
return (length*cos(angle))+X, (length*sin(angle))+Y
end
-- set X and Y coordinates about wich to rotate a texture. returns a table that contains all coordinates for angles 0-360
-- resolutin will set the resolution of angles should be bigger or equal to 0 (0 is no resolution and table might grow infinitly)
-- ULx, ULy, LLx, LLy, URx, URy, LRx, LRy is the initial transformation of the texture
function TB:CreateRotationSetup(X, Y, resolution, ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
local ULxtable = {}
local ULytable = {}
local LLxtable = {}
local LLytable = {}
local URxtable = {}
local URytable = {}
local LRxtable = {}
local LRytable = {}
rotfunction = function(angle)
if ULxtable[angle] then
return ULxtable[angle], ULytable[angle], LLxtable[angle], LLytable[angle], URxtable[angle], URytable[angle], LRxtable[angle], LRytable[angle]
end
if resolution and (resolution > 0) then
angle = floor(angle/resolution+.5)*resolution
end
if angle >= 360 then
angle = angle - floor(angle/360)*360
elseif angle < 0 then
angle = angle + ceil((abs(angle)/360))*360
end
if ULxtable[angle] then
return ULxtable[angle], ULytable[angle], LLxtable[angle], LLytable[angle], URxtable[angle], URytable[angle], LRxtable[angle], LRytable[angle]
end
local radangle = rad(angle)
local subtable = {}
ULxT, ULyT = rotatepoint(X,Y,ULx,ULy,radangle)
LLxT, LLyT = rotatepoint(X,Y,LLx,LLy,radangle)
URxT, URyT = rotatepoint(X,Y,URx,URy,radangle)
LRxT, LRyT = rotatepoint(X,Y,LRx,LRy,radangle)
ULxtable[angle] = ULxT
ULytable[angle] = ULyT
LLxtable[angle] = LLxT
LLytable[angle] = LLyT
URxtable[angle] = URxT
URytable[angle] = URyT
LRxtable[angle] = LRxT
LRytable[angle] = LRyT
return ULxT, ULyT, LLxT, LLyT, URxT, URyT, LRxT, LRyT
end
return rotfunction
end

feed the returned function a angle and it will spit out all 8 coordinates (makes it easier to put it in a SetTexCoord function

:SetTexCoord(RotationFunction(angle))

Rollback Post to RevisionRollBack

To post a comment, please login or register a new account.

the goal of that code is to be able to rotate a pretransformed texture about any point and chaching the result in a table

the getRotationTable function returns a empty table with a sweet metafunction that will populate the table if you ask for a angle of rotation :)

so you can rotate the texture say to 180deg you simply access the table[180] and it will return table[180].ULx, table[180].ULy, table[180].LLx, table[180].LLy, table[180].URx, table[180].URy, table[180].LRx, table[180].LRy

then we simply plugin our result into the :SetTexCoord function which can be done like this

and presto you have now rotated you texture

some quircks about the table:

it will only store date between 0 and 360 if you access anything bigger or smaller the meta table will recalculate your input to be within the correct range and then either return cached data or calculate the data and cache it

the rotation is counterclockwise if you increase your angle

what is this meant for? basically its meant for textures that get rotated as an animation ingame but you can technically use it for fixed rotations to. be warned the table can grow to infinate size since it will also take decimal degrees like 1.2324235434655 and cache that result so if you are doing anymations try to stay with a cetrain set of angles and just use those :)

want to thank Wobin and Xinhuan about their insights about how texture transformations work (its kinda quirky imo)

any ideas on how to make this more efficent would be much appreciated

Edit: added a resolution arg which limits the table to multiples of that resolution should be a value between 0 and 360 :)

will see if i can adjust it so that it will always scalle properly

That should be easily fixed if needed:

Sounds reasonable. I only suggested it because you called it a "quirk". :P

with quirk i meant the table behaves in not necessarily in a way you would suspect :) since calling 361 actually calculates/sets/calls 1 :)

i am able to shrink memory usage to 69% but at the same time increase CPU usage 2.8 times

any ideas for what would be best? go for the smaller memory footprint or the faster calculations? (the change in cpu usage is only for calculating the new values at an unknown angle if you already know the angle the CPU usage is virtually 0 either way)

Think about it this way. which is easier to upgrade, memory or cpu? so therefore which has higher priority? lower CPU usage should -always- trump memory.

except in this case, where results are cached, the speed penalty is only paid once -- so I would go with the reduced memory footprint.

jm2c,

-Pach

should run with smaller memory footprint and faster calculations

it will now return a function instead of a table

feed the returned function a angle and it will spit out all 8 coordinates (makes it easier to put it in a SetTexCoord function