Simulating graphics.rotate by using other functions?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Cipheroid
Prole
Posts: 9
Joined: Fri Feb 24, 2017 7:52 am

Simulating graphics.rotate by using other functions?

Post by Cipheroid »

Is there any way to simulate graphics.rotate by using graphics.shear and graphics.scale? (Does not need to be 360*)
Every attempt I tried at doing this led to things being disproportionate or skewed to an absurd size.
I am mainly interested in this to make things easier to distort for special effects. :o:
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Simulating graphics.rotate by using other functions?

Post by raidho36 »

Emulation implies that it will be harder to accomplish, results will be sub-par and it will be more computationally expensive. Just get good with the normal tools.
User avatar
Davidobot
Party member
Posts: 1226
Joined: Sat Mar 31, 2012 5:18 am
Location: Oxford, UK
Contact:

Re: Simulating graphics.rotate by using other functions?

Post by Davidobot »

What is the problem with using graphics.rotate? Is it that you want to set the center of rotation? If that's the case, you need to first translate the center to the position you wish to be rotated around, rotate, and then translate back:

Code: Select all

love.graphics.translate(dx, dy)
love.graphics.rotate(1.2)
love.graphics.translate(-dx, -dy)
Code is untested.
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
Xugro
Party member
Posts: 110
Joined: Wed Sep 29, 2010 8:14 pm

Re: Simulating graphics.rotate by using other functions?

Post by Xugro »

It is pretty simple since rotate, scale and shear are all linear transformations described by matrices (see source: /src/common/Matrix.cpp). You just have to multiply them and compare coefficients.

I attached a simple example.
Attachments
rotate_as_scale_and_shear.love
(393 Bytes) Downloaded 114 times
Last edited by Xugro on Wed Jul 26, 2017 9:28 pm, edited 2 times in total.
Cipheroid
Prole
Posts: 9
Joined: Fri Feb 24, 2017 7:52 am

Re: Simulating graphics.rotate by using other functions?

Post by Cipheroid »

What is the problem with using graphics.rotate? Is it that you want to set the center of rotation? If that's the case, you need to first translate the center to the position you wish to be rotated around, rotate, and then translate back:
There is nothing wrong with using graphics.rotate. I am just trying to see if there is a way to simulate graphics.rotate by using graphics.shear and graphics.scale, which would be useful to make the screen trippy and nauseous.

For example: graphics.shear(-1,1) rotates the screen 45 degrees, but everything will become larger past this point. Compensating this with graphics.scale is possible. There are also certain locations that will need to be compensated also, something of which I was not able to do yet.

(Update)
I was able to make a function that does most of this, however it is buggy. The screen shrinks in certain locations.
shear(-45,45) rotates the screen 45 degrees.

Code: Select all

shear=function(_,a,b)
    if a or b then
        c.a=a or c.a
        c.b=b or c.b
    elseif not (a or b) then
        a=math.abs(c.a)
        b=math.abs(c.b)
        a=(a/(a+45))
        b=(b/(b+45))
        graphics.scale(1-a,1-b)
        graphics.shear(c.a/45,c.b/45)
    end
end
There could be better ways to do this, but I was pretty much stuck there.

(Update)
It is pretty simple since rotate, scale and shear are all linear transformations described by matrices (see source: /love/src//src/common/Matrix.cpp). You just have to multiply them and compare coefficients.
Thanks, this might be useful! :D
MasterLee
Party member
Posts: 141
Joined: Tue Mar 07, 2017 4:03 pm
Contact:

Re: Simulating graphics.rotate by using other functions?

Post by MasterLee »

Code: Select all

Rotation Matrix is
cos(r) -sin(r)
sin(r) cos(r)

now when you apply is to an vector
x y
you will get
x*cos(r)-y*sin(r) y*cos(r)+x*sin(r)

Scale Matrix:
S 0
0 S
Shear Matrix is:
1 Sx
Sy 1

Now the Problem is
now when you first apply scale to an vector
x y
you will get 
x*S y*S
now Shear Matrix gives
x*S+y*S*Sx y*S+x*S*Sx

Now remember what we wan't
So first we can replace S with cos(r)
So we will get
x*cos(r)+y*cos(r)*Sx y*cos(r)+x*cos(r)*Sx
Now Sx and is a little bit more complicated
it should be
Sx=-sin(r)/cos(r)
Sy=sin(r)/cos(r)
an we get the rotation function as:
x*cos(r)-y*sin(r) y*cos(r)+x*sin(r)

So we should fill
Scale(cos(r),cos())
Shear(-sin(r)/cos(r),sin()/cos(r))

But now there is a problem
When rotation is 90° cos becomes zero
JoshGrams
Prole
Posts: 33
Joined: Sat May 27, 2017 10:58 am

Re: Simulating graphics.rotate by using other functions?

Post by JoshGrams »

This may not work for your purposes, but the classic thing is to perform a rotation by doing three shear operations:

Code: Select all

local kx, ky = -math.tan(angle/2), math.sin(angle)
love.graphics.shear(kx, 0)
love.graphics.shear(0, ky)
love.graphics.shear(kx, 0)
This was popularized by Alan Paeth's 1986 paper A Fast Algorithm for General Raster Rotation. I believe it is still occasionally used for image processing because the way a shear works along an axis and is area-preserving gives you slightly less error in the final result (for the same interpolation function: you can still use linear/bilinear/sinc/etc.).
Attachments
rotate-by-shearing.love
(356 Bytes) Downloaded 121 times
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 54 guests