2011-06-21 228 views
11

我有谷歌地图图标,在使用MarkerImage在地图上绘图之前,需要旋转某些角度。我使用PIL在Python中执行旋转,生成的图像与原始图像大小相同 - 32x32。例如,使用以下默认谷歌地图标记:获取旋转图像中点的新x,y坐标

# 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) 

所得图像是icon rotated 30 degrees counter-clockwise

棘手位是: icon before rotation ,一个30度康特时针旋转,使用以下Python代码实现在使用新的旋转图像创建MarkerImage时获取新的锚点。这需要成为图标的尖端。默认情况下,定位点是底部中间[在x,y坐标中定义为(16,32),其中(0,0)是左上角]。有人可以向我解释我怎样才能在JavaScript中轻松解决这个问题?

谢谢。

更新2011年6月22日: 已张贴错误的旋转图像(原来是逆时针330度)。我纠正了这一点。还添加了重新采样(Image.BICUBIC),使旋转图标更清晰。

+0

@Trufa:谢谢你的建议。 –

回答

20

要计算旋转点的位置,您可以使用rotation matrix

转换为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...] 
+0

谢谢。这正是我需要的。 –

+0

@Simon Kagwi:谢谢你纠正,不知道那里发生了什么...... – pimvdb

6

约0,0旋转的公式是:

x1 = cos(theta) x0 - sin(theta) y0 
y1 = sin(theta) x0 + cos(theta) y0 

但是,这对于普通轴,绕0,0。 “图形”轴顺时针旋转PIL。另外,它围绕图像的中心。最后令人困惑的是,图像的大小可能会发生变化,这需要在最终结果中进行说明。

程序:取原点,减去图像中心,应用“图形轴”校正旋转,找到新的图像大小,加回新图像的中心位置。

旋转用图形轴是:

x1 = cos(theta) x0 + sin(theta) y0 
y1 = -sin(theta) x0 + cos(theta) y0 

16,32 - 16,16为0,16,旋转30度顺时针旋转(基于你的图像)给出一个点COS(-30)* 0 + sin(-30)* 16,-sin(-30)* 0 + cos(-30)* 16 = -8,13.86。最后一步是添加旋转位置的中心位置。

+0

你能解释一下“常规”和“图形”轴之间的区别吗?主要的不同似乎是哪个坐标有一个减法,但我不明白为什么。 – Michael

0

在图像,下为正Y和向右为正X.然而,应用rotation formula,我们需要向上为正Y.因此,步骤1将应用f(x,y) = f(x,h-y),其中'h'是图像的高度。假设图像相对于x0,y0旋转。那么你需要将你的起源转变为这一点。因此,第2步将是f(x,y) = f(x-x0,y-y0)。在此阶段(即两步之后),您的新坐标将为​​,h-y-y0。您现在已准备好应用旋转公式

x1 = x*cos(theta) - y*sin(theta) 

y1 = xsin(theta) + ycos(theta) 

使用步骤二后获得的x和y的值。 你会得到

x1 = (x-x0)*cos(theta) - (h-y-y0)*sin(theta) 

y1 = (x-x0)*sin(theta) + (h-y-y0)*cos(theta) 

现在,撤消在步骤2和步骤1(按顺序)完成转换。

撤消第二步后:xNew = x1 + x0yNew = y1 + y0

撤销第一步后:xNew = x1 + x0yNew = h - (y1 + y0)

这给了你:

xNew = (x-x0)*cos(theta) - (h-y-y0)*sin(theta) + x0 

yNew = -(x-x0)*sin(theta) - (h-y-y0)*cos(theta) + (h-y0)