ATAN calculation fails when values are scaled
Im animating sprites w javacript - these sprites consist of a container DIV and the firstChild is an absolute positioned IMG. The image is comprised of 16 vertical views/angles of the object. When the object moves from A to B, the ATAN2 function calculates the style=top: value appropriate to the direction the object is traveling in. This all works except for another aspect of the s开发者_运维问答prite - they can change their size. The default size of the sprite is 24px (wide) and this does work with ATAN2, but as soon as the sprite is made bigger the calculation misaligns the sprite's frame-strip. Below is the code, x1 - y1 are the from and to positions, while s is the size (width). the value 128 is the maximum size - and the bracked values are of a sprite allowed and the last calculation assumes this, then computes for the actual size with *(s/128) ...
function P_angle(x1,x2,y1,y2,s)
{
var v=parseInt(Math.atan2(x2-x1,y2-y1)/(Math.PI/180)+180)
return (v>348.75?0:v>326.25?-128:v>303.75?-256:v>281.25?-384:v>258.75?-512:v>236.25?-640:v>213.75?-768:v>191.25?-896:v>168.75?-1024:v>146.25?-1152:v>123.75?-1280:v>101.25?-1408:v>78.75?-1536:v>56.25?-1664:v>33.75?-1792:v>11.25?-1920:0)*(s/128);
}
In the first line you do a floating point calculation and pass the result to a function expecting a string argument... you are saved by implicit conversion, but it's ugly.
The huge conditional in your second line rounds the angle off to the nearest multiple of 22.5 degrees, wrapping around and mapping to negative multiples of 128, then multiplies it with s
divided by 128... was it originally designed for 128 pixel sprites? Anyway, you should just be able to do this:
function P_angle(x1,x2,y1,y2,s)
{
return s*(Math.round(Math.atan2(x2-x1,y2-y1)*(8/Math.PI)-8)%16);
}
You don't say how large the misalignment is with your original code, but I suspect it is caused by rounding errors when dividing out the 128 factor, and that you were just lucky that everything rounded right for 24 pixel sprites. With the version here, you are certain to return an exact multiple of s
.
精彩评论