[英]Get new x,y coordinates of a point in a rotated image
I have Google Maps icons which I need to rotate by certain angles before drawing on the map using MarkerImage . 我有谷歌地图图标,我需要在使用MarkerImage在地图上绘制之前按特定角度旋转。 I do the rotation on-the-fly in Python using PIL, and the resulting image is of the same size as the original - 32x32. 我使用PIL在Python中即时轮换,结果图像与原始图像大小相同 - 32x32。 For example, with the following default Google Maps marker: 例如,使用以下默认的Google地图标记: , a 30 degrees conter-clockwise rotation is achieved using the following python code: ,使用以下python代码实现30度顺时针旋转:
# full_src is a variable holding the full path to image
# rotated is a variable holding the full path to where the rotated image is saved
image = Image.open(full_src)
png_info = image.info
image = image.copy()
image = image.rotate(30, resample=Image.BICUBIC)
image.save(rotated, **png_info)
The resulting image is 得到的图像是
The tricky bit is getting the new anchor point to use when creating the MarkerImage using the new rotated image. 棘手的一点是在使用新的旋转图像创建MarkerImage时使用新的锚点。 This needs to be the pointy end of the icon. 这需要是图标的尖端。 By default, the anchor point is the bottom middle [defined as (16,32) in x,y coordinates where (0,0) is the top left corner]. 默认情况下,锚点是底部中间[在x,y坐标中定义为(16,32),其中(0,0)是左上角]。 Can someone please explain to me how I can easily go about this in JavaScript? 有人可以向我解释如何在JavaScript中轻松解决这个问题吗?
Thanks. 谢谢。
Update 22 Jun 2011: Had posted the wrong rotated image (original one was for 330 degrees counter-clockwise). 2011年6月22日更新:发布了错误的旋转图像(原始图像是逆时针旋转330度)。 I've corrected that. 我已经纠正了这一点。 Also added resampling (Image.BICUBIC) which makes the rotated icon clearer. 还添加了重采样(Image.BICUBIC),使旋转的图标更清晰。
To calculate the position of a rotated point you can use a rotation matrix . 要计算旋转点的位置,可以使用旋转矩阵 。
Converted into JavaScript, this calculates the rotated point: 转换为JavaScript,计算旋转点:
function rotate(x, y, xm, ym, a) {
var cos = Math.cos,
sin = Math.sin,
a = a * Math.PI / 180, // Convert to radians because that is what
// JavaScript likes
// Subtract midpoints, so that midpoint is translated to origin
// and add it in the end again
xr = (x - xm) * cos(a) - (y - ym) * sin(a) + xm,
yr = (x - xm) * sin(a) + (y - ym) * cos(a) + ym;
return [xr, yr];
}
rotate(16, 32, 16, 16, 30); // [8, 29.856...]
The formula for rotations about 0,0 is: 旋转公式约为0,0是:
x1 = cos(theta) x0 - sin(theta) y0
y1 = sin(theta) x0 + cos(theta) y0
But that's for regular axes, and rotation about 0,0. 但这是常规轴,旋转约为0,0。 The PIL rotation is clockwise with "graphics" axes. PIL旋转顺时针方向,带有“图形”轴。 Plus, it's around the center of the image. 另外,它位于图像的中心附近。 The final confusing thing is that the size of the image can change, which needs to be accounted for in the final result. 最后令人困惑的是图像的大小可能会发生变化,这需要在最终结果中加以考虑。
Procedure: take original point, subtract off center of image, apply "graphics axes" corrected rotation, find new size of image, add back center position of new image. 步骤:取原点,减去图像中心,应用“图形轴”校正旋转,找到新的图像尺寸,加回新图像的中心位置。
Rotation using graphics axes is: 使用图形轴旋转是:
x1 = cos(theta) x0 + sin(theta) y0
y1 = -sin(theta) x0 + cos(theta) y0
16,32 - 16,16 is 0, 16. Rotate 30 degrees clockwise rotation (based on your images) gives a point cos(-30)*0+sin(-30)*16, -sin(-30)*0+cos(-30)*16 = -8, 13.86. 16,32 - 16,16为0,16。顺时针旋转30度(根据你的图像)给出一个点cos(-30)* 0 + sin(-30)* 16,-sin(-30)* 0 + cos(-30)* 16 = -8,13.86。 The final step is adding back the center position of the rotated position. 最后一步是添加旋转位置的中心位置。
In an image, downwards is positive Y and rightwards is positive X. However, to apply the rotation formula , we need upwards as positive Y. Therefore, step 1 would be to apply f(x,y) = f(x,hy)
, where 'h' is the height of the image. 在图像中,向下是正Y,向右是正X.但是,要应用旋转公式 ,我们需要向上作为正Y.因此,步骤1将应用f(x,y) = f(x,hy)
,其中'h'是图像的高度。 Let's say the image is rotated with respect to x0,y0. 假设图像相对于x0,y0旋转。 You'd then need to transform your origin to this point. 然后,您需要将原点转换为此点。 Therefore, step 2 would be f(x,y) = f(x-x0,y-y0)
. 因此,步骤2将是f(x,y) = f(x-x0,y-y0)
。 At this stage (ie after the two steps), your new co-ordinates would be x-x0
, hy-y0
. 在这个阶段(即两个步骤之后),你的新坐标将是x-x0
, hy-y0
。 You're now ready to apply the rotation formula 您现在已准备好应用旋转公式
x1 = x*cos(theta) - y*sin(theta)
y1 = xsin(theta) + ycos(theta)
Use the values of x and y obtained after step two. 使用在第二步之后获得的x和y的值。 You'd get 你会得到的
x1 = (x-x0)*cos(theta) - (h-y-y0)*sin(theta)
y1 = (x-x0)*sin(theta) + (h-y-y0)*cos(theta)
Now, undo transformations done in step 2 and step 1 (in that order). 现在,撤消在步骤2和步骤1中完成的转换(按此顺序)。
After undoing step2: xNew = x1 + x0
and yNew = y1 + y0
撤消step2后: xNew = x1 + x0
和yNew = y1 + y0
After undoing step1: xNew = x1 + x0
and yNew = h - (y1 + y0)
撤消step1后: xNew = x1 + x0
和yNew = h - (y1 + y0)
This gives you: 这给你:
xNew = (x-x0)*cos(theta) - (h-y-y0)*sin(theta) + x0
yNew = -(x-x0)*sin(theta) - (h-y-y0)*cos(theta) + (h-y0)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.