Page 1 of 1

Simulating graphics.rotate by using other functions?

Posted: Wed Jul 26, 2017 9:24 am
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:

Re: Simulating graphics.rotate by using other functions?

Posted: Wed Jul 26, 2017 9:59 am
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.

Re: Simulating graphics.rotate by using other functions?

Posted: Wed Jul 26, 2017 6:19 pm
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.

Re: Simulating graphics.rotate by using other functions?

Posted: Wed Jul 26, 2017 8:00 pm
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.

Re: Simulating graphics.rotate by using other functions?

Posted: Wed Jul 26, 2017 8:13 pm
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

Re: Simulating graphics.rotate by using other functions?

Posted: Fri Jul 28, 2017 8:53 am
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

Re: Simulating graphics.rotate by using other functions?

Posted: Fri Jul 28, 2017 1:53 pm
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.).