简体   繁体   English

获取旋转图像中某点的新x,y坐标

[英]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 得到的图像是 图标逆时针旋转30度

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-x0hy-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 + x0yNew = y1 + y0

After undoing step1: xNew = x1 + x0 and yNew = h - (y1 + y0) 撤消step1后: xNew = x1 + x0yNew = 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.

相关问题 在P5 js中找到围绕其中心点旋转的正方形平面的顶点坐标(x,y,z) - Finding the coordinates (x,y,z) of vertices of a square plane rotated about its center point in P5 js 如何找到旋转矢量的x,y坐标 - How to find the x,y coordinates of a rotated vector 如何获取画布中图像的坐标xy - How to get coordinates x y of image in a canvas 从Javascript画布获取点的未翻译,未旋转(x,y)坐标 - Get un-translated, un-rotated (x,y) coordinate of a point from a Javascript canvas 将(旋转的)ImageOverlay中的X和Y坐标转换为纬度和经度 - Transform X and Y coordinates inside a (rotated) ImageOverlay to latitude and longitude 如何在JavaScript中计算旋转3D立方体的x和y坐标? - How to calculate x and y coordinates of a rotated 3D cube in JavaScript? 无论设备大小如何,获取鼠标在图像上单击的坐标(X,Y) - Get Coordinates (X,Y) of mouse click on image regardless of the device size 获取图像内预定义区域的所有 x、y 坐标 - Get all x, y coordinates of a predefined area within an image 如何使用x和y坐标从图像中获取像素颜色? - how to get pixel color from image using x and y coordinates? 找到阿基米德螺旋上的点的x,y坐标 - Finding x,y coordinates of a point on an Archimedean spiral
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM