PDA

View Full Version : help programming math for sprites


Evil Bunny
27 Nov 2006, 19:06
I've been busying myself with photoshop script. I want write a set of tools to automate sprite generation, have a few scripts do all the hard work like rotateion of projectiles, aiming launchers up and down, drawing and hiding them, squeezing crates.

Well, so i started off with the squeeze, guessing that to be the easiest, and it was. After polishing up my math a little. However now i'm facing the problem of rotation and I can't get my head around it.

I need a function which can handle the following; I have a 2 x and 2 y coördinates, one of the layer center and one of the document center. And I have the amount of frames it has to make a full rotation. Can anyone help me write a function to calculate the distance (x / y) a copy of my original layer has to move after it's rotation has been applied?

For sake of future developement it will eventually require to 'swing' rather then make a full 360 (for crates on chutes). So at that point a drawback angle and acceleration would come into it but i'm pretty sure i can figure that out.

And for the fun of it, here's a crate I automated with the squeeze.

Alien King
27 Nov 2006, 19:09
I've been busying myself with photoshop script. I want write a set of tools to automate sprite generation, have a few scripts do all the hard work like rotateion of projectiles, aiming launchers up and down, drawing and hiding them, squeezing crates.

Well, so i started off with the squeeze, guessing that to be the easiest, and it was. After polishing up my math a little. However now i'm facing the problem of rotation and I can't get my head around it.

I need a function which can handle the following; I have a 2 x and 2 y coördinates, one of the layer center and one of the document center. And I have the amount of frames it has to make a full rotation. Can anyone help me write a function to calculate the distance (x / y) a copy of my original layer has to move after it's rotation has been applied?

For sake of future developement it will eventually require to 'swing' rather then make a full 360 (for crates on chutes). So at that point a drawback angle and acceleration would come into it but i'm pretty sure i can figure that out.

And for the fun of it, here's a crate I automated with the squeeze.

Whilst I can't help you, I do like the idea of the work you've been doing.

Vader
27 Nov 2006, 19:55
Well, you need to use trigonometry to find out the angle from x and y. I might have misunderstood what you're trying to do, but I'll try to give an idea of what you should do. It's a while since I tried this so I'll be rusty but I'm sure someone can correct me. ;) I've attached an image for reference.

We know your triangle is right-angled because there are only two changing angles. Those angles are A and B and the point of rotation is at A. That's the angle you need to work out, and here might be how to do it:


tan A = opposite leg to A / adjacent leg to A

Or in this case:

tan A = y / x

Assuming x is 30 and y is 15 (if point A is 0,0 then an x coordinate of 30 is the same as an x length of 30 and the same for y and 15), the following will be true:

tan A = 15 / 30 or tan A = 0.5

So now you need to use a scientific calculator (or the script in this case) to work out what that means. I think this works for demonstrative purposes:

Run calc and click View > Scientific.

Type in 0.5, check the "Inv" checkbox and click the "tan" button. The result will be 26.565051177077989351572193720453.

Obviously you'll want to work in integers, so this would equal 27 if you're rounding up.

I have no idea how to script that into photoshop, but that's the basic maths for it if I've understood you correctly. Oh, and h on the triangle is the hyptonuse, the length of which can be calculated using Pythagoras' theorem:

a² + b² = c²

Or in this case:

x² + y² = h²

That's not necessary for working out the angle, though.

Evil Bunny
27 Nov 2006, 20:29
Hmm, well I know the basic concepts of using cos and sin, i can calculate my ration and my angle from which it starts but that's where I get stuck. My angle doesn't go above 90 deg and i need it to know where in the 360 full circle it is and how to calculate the rest from there.

Vader
27 Nov 2006, 20:36
90 degrees will be when y is 0 and x isn't, or vice versa.

Evil Bunny
27 Nov 2006, 20:51
yeah, it's 90 when y's 0.

Vader
27 Nov 2006, 21:56
When your hypotenuse goes from vertical to horizontal, the y coordinate will need to become negative, right?

I'm not sure what you are asking, but is this it (See attachment)?

AndrewTaylor
28 Nov 2006, 10:27
Nice work, I like it. Try looking on Mathworld (http://mathworld.wolfram.com/); they know everything of this kind and the search is pretty good. It's all formulae rather than functions but I'm sure you can convert it.

If I knew exactly what you were after I'd probably be more help.

Oh, and Vader, I think you can use the "squared" character from character map here.

Lyndon
28 Nov 2006, 13:16
your squash is right, its arching outwards, but your squeeze is wrong, should be arching inwards, currently both arch outwards

AndrewTaylor
28 Nov 2006, 13:17
That depends what effect he's going for, surely?

Vader
28 Nov 2006, 15:28
If I knew exactly what you were after I'd probably be more help.

For once we agree on something. ;)

Oh, and Vader, I think you can use the "squared" character from character map here.

I'll edit that now, then.

Evil Bunny
28 Nov 2006, 19:16
right, thanks for all the input guys, and for the site. I'm afraid i'm still not managing. I'll write up the parts of my function i know are working.


function rotate(Layer, angle) {
var Doc = Layer.parent;

/* Get document center positions */
var doc_x = Doc.width / 2;
var doc_y = Doc.height / 2;

/* Get layer center positions */
var lay_x = (Layer.bounds[2] - Layer.bounds[0]) / 2 + Layer.bounds[0];
var lay_y = (Layer.bounds[3] - Layer.bounds[1]) / 2 + Layer.bounds[1];

/* Calculate difference between layer and document center. */
var dsp_x = lay_x - doc_x;
var dsp_y = lay_y - doc_y;

/* Calculat 3rd side */
var dsp_z = Math.sqrt( dsp_x * dsp_x + dsp_y * dsp_y );

/* Calculate angle */
var dsp_agl = Math.atan(dsp_x / dsp_y) * 180 / Math.PI;

/* Add to angle */
var newAngl = dsp_agl + (angle || 360);

/* Calculate new position and apply negative. */
var new_dsp_x = turnCW * x_dir * (dsp_z * Math.sin(newAngl * Math.PI / 180)); // dsp_x
var new_dsp_y = turnCW * y_dir * (dsp_z * Math.cos(newAngl * Math.PI / 180)); // dsp_y

/* Recalculate from document top left rather then document center */
var new_x = doc_x + new_dsp_x;
var new_y = doc_y + new_dsp_y;

/* Calculate movement */
var move_x = new_x - lay_x;
var move_y = new_y - lay_y;

/* move layer */
Layer.translate(move_x, move_y);
}


@ lyndon;
Well, I'm not really sure, the way i've got it now it will do 2 things; it will blow the whole thing up when going outward, as well as stretch on x or y, Works alright for me but I might aswell have a look at some other ways of making the squeeze.

bloopy
29 Nov 2006, 09:22
Okay, lets say in frame #1 that the layer centre is directly vertical above the document centre. So in frame #1, x of the layer centre equals x of the document centre. In other words, the starting angle is 0 and y of the layer centre is at its maximum value.

To calculate the new x and y of the layer centre for any frame, you just need to know the # of the new frame (N), the total number of frames (T), and the radius (R).

A = (360/T) * (N-1) <-- calculating the angle of rotation for next frame, frame N.

x = sin(A) * R

y = cos(A) * R

:D Am I right?


edit: if you don't know the frame number you're up to, you can calculate it (xOld and yOld are the old x and y :)):

B = sin-1(xOld/R)

if yOld < 0 then B = 180-B <-- accounting for bottom half of circle

N = 1 + (T*B)/360

Evil Bunny
29 Nov 2006, 12:42
lol, yeh, the frames thing i've got, that's easy enough. Also i've almost got it... i think. Well i got it circling the document center now! So if i can figure out how to get an angle between 0 and 360 instead of twice -90 to 90 then i can wrap this thing up and move on to building this information.

As far layers where the center is the same as that of the document, that's easy. they don't move on rotation because the center position never changes while rotating.


Here's a good question though. Can you lot let me know if you guys are using photoshop CS or CS2? Because this only works for CS and above. I'd like to get me some idea of how many people will be able to work with it.

AndrewTaylor
29 Nov 2006, 13:28
Arctangents are a pain for 0-360 angles. Check to see if there's an atan2 function. Most languages that have atan have atan2, which is similar but gives a 360 degree answer (and the syntax is just slightly different).

bloopy
29 Nov 2006, 20:22
Why do you need arctangents? My solution just uses cos, sin, and inverse sin.

I have Photoshop CS2 but I'm a newbie with it really.

Evil Bunny
29 Nov 2006, 20:36
hey! thanks a bunch Andrew, that did the trick. I've got it rotating now... well sorta, something's off in my positioning and the move method photoshop offers is also being a star-star-star-star. But at least I can go on from here! Don't stay up for a pic caus this is a long term project.