最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

math - how to get crop coordinates after a rotation javascript - Stack Overflow

programmeradmin4浏览0评论

I need to retain coordinate information following a rotation and am struggling with the necessary math.

I have an image, with certain crop coordinates. These coordinates are given as the following object:

{
      h:  139.68333435058594,
      w:  139.68333435058594,
      x:  60.31666564941406,
      x2: 200,
      y:  80,
      y2: 219.68333435058594
}

I am then rotating this image (it is a canvas element) but I would like the new coordinates to accurately reflect the rotation, leaving the original crop intact.

e.g. if the top left quarter of a 400x400 image is selected the returned coordinates would be x:0, y:0, x2:200, y2:200. When rotated -90 degrees to the left, the new coordinates should be : x:0, y:200, x2:200, y:400.

How would I write a function to calculate these new coordinates?

Many thanks.

To help visualize this question properly I have included a quick image:

EDIT: The large square in the image above is the photo that I am rotating. It is being rotated around its midpoint and the crop coordinates are relative to the image itself. Upon rotation the actual coordinate plane is reset prior to recalculating the new coordinates meaning that the top left point of the image/container will always be 0,0.

I need to retain coordinate information following a rotation and am struggling with the necessary math.

I have an image, with certain crop coordinates. These coordinates are given as the following object:

{
      h:  139.68333435058594,
      w:  139.68333435058594,
      x:  60.31666564941406,
      x2: 200,
      y:  80,
      y2: 219.68333435058594
}

I am then rotating this image (it is a canvas element) but I would like the new coordinates to accurately reflect the rotation, leaving the original crop intact.

e.g. if the top left quarter of a 400x400 image is selected the returned coordinates would be x:0, y:0, x2:200, y2:200. When rotated -90 degrees to the left, the new coordinates should be : x:0, y:200, x2:200, y:400.

How would I write a function to calculate these new coordinates?

Many thanks.

To help visualize this question properly I have included a quick image:

EDIT: The large square in the image above is the photo that I am rotating. It is being rotated around its midpoint and the crop coordinates are relative to the image itself. Upon rotation the actual coordinate plane is reset prior to recalculating the new coordinates meaning that the top left point of the image/container will always be 0,0.

Share Improve this question edited Sep 26, 2012 at 14:48 gordyr asked Sep 26, 2012 at 14:35 gordyrgordyr 6,29614 gold badges67 silver badges123 bronze badges 7
  • Are you rotating the larger square from its center? – Shmiddty Commented Sep 26, 2012 at 14:44
  • The large square (the photo in this case) is being rotated around its mid point. I just need to recalculate the crop area so that it gets rotated as well. – gordyr Commented Sep 26, 2012 at 14:45
  • Or, more generally, what is the pivot point on which you are rotating? – Shmiddty Commented Sep 26, 2012 at 14:45
  • The new coordinates of the "crop area" will be dependent on where the canvas is rotated – Shmiddty Commented Sep 26, 2012 at 14:46
  • Not in this case as for this app you will need to imagine the canvas being destroyed and a new version recreated to match the rotation. To be a little more clear, all crop coordinates are relative to the container and upon rotation all container coordinates are reset, i.e. the top left corner will ALWAYS be 0,0. I hope that makes sense – gordyr Commented Sep 26, 2012 at 14:50
 |  Show 2 more ments

3 Answers 3

Reset to default 3

This function uses the Rotation Matrix algorithm

function rotate(x, y, xm, ym, a) {
    var cos = Math.cos, sin = Math.sin,
    a = a * Math.PI / 180, // Convert to radians 
    // 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];
}

alert(rotate(0, 0, 200, 200, -90));​ // 0,400

JSFiddle

Top left corner will be:

0, heightImg - heightCrop

Bottom Right will be:

widthCrop, widthImg

This is assuming the crop is snug with the top left corner before rotation.

I'll work out the general math in a bit.

The formulas to rotate a point (A) around a point (B) by angle (C) are as follows:

N.x = (A.x-B.x) * cos(c) - (A.y-B.y) * sin(c) + B.x
N.y = (A.y-B.y) * cos(c) + (A.x-B.x) * sin(c) + B.y

We can reduce these since we're rotating by 90 degrees. [cos(90) = 0, sin(90)=1]

N.x = 0 - (A.y-B.y) + B.x = B.x + B.y - A.y
N.y = 0 + (A.x-B.x) + B.y = B.y + A.x - B.x

So using this formula with the coordinates of the top-left point will give you the bottom-left point. (The x will be correct, but you'll have to subtract the crop area's height to get the correct y value for the new top-left point)

The matrix for a 90 degree counterclockwise rotation around the (0,0) point (in your coordinate system) is

  0 1
 -1 0

Which translates in code to:

new_x = y; new_y = -x;

But you want to rotate around (200,200), so you will need to move your points before rotating them, and move them back afterwards.

new_x = (y-200) + 200;
new_y = -(x-200) + 200;

Simplified, this is just

new_x = y; new_y = 400-x;

You should be able to transform all of the crop coordinates like that.

发布评论

评论列表(0)

  1. 暂无评论