Snukus
Snukus

Reputation: 1302

Points on a rotated rectangle

I'm attempting to calculate the bottom-left point in a rectangle as it is rotated around. I've attempted to Google it, but apparently I'm missing something. I'm attempting to use a transformation matrix to calculate the point.

For my setup, I have a rectangle clip called "test" and a clip called "pnt" that I'm trying to keep on the lower left point. Here is the code for my demo. I've just thrown this onto the first frame of the timeline to test:

//declare initial position of points
pnt.x = (test.x - test.width/2);
pnt.y = (test.y + test.height/2);

//distance between corner and center
var dx:Number = pnt.x - test.x;
var dy:Number = pnt.y - test.y;

addEventListener(Event.ENTER_FRAME,rotate);


//x' = xc + dx cos(theta) - dy sin(theta)
//y' = yc + dx sin(theta) + dy cos(theta)
function rotate(e:Event):void{
    test.rotation++;

    // use the transformation matrix to calculate the new x and y of the corner
    pnt.x = test.x + dx*Math.cos(test.rotation*(Math.PI/180)) - dy*Math.sin(test.rotation*(Math.PI/180));
    pnt.y = test.y + dx*Math.sin(test.rotation*(Math.PI/180)) + dy*Math.cos(test.rotation*(Math.PI/180));

    trace("X: " + Math.cos(rotation));
    trace("Y: " + pnt.y);
    // calculate the new distance to the center
    dx = pnt.x - test.x;
    dy = pnt.y - test.y;
}

Upvotes: 3

Views: 2197

Answers (2)

Campbeln
Campbeln

Reputation: 2990

For those of you who found this as I did via the Google...

Here is the above answer in JavaScript/jQuery form, where $element is the $('#element') jQuery object, iDegrees is the angle you wish to rotate, iX/iY are the coordinates to the point you wish to know the destination of, and iCenterXPercent/iCenterYPercent represent the percentage into the element (as per CSS's transform-origin) where the rotation will occur:

function XYRotatesTo($element, iDegrees, iX, iY, iCenterXPercent, iCenterYPercent) {
    var oPos = $element.position(),
        iCenterX = ($element.outerWidth() * iCenterXPercent / 100),
        iCenterY = ($element.outerHeight() * iCenterYPercent / 100),
        iRadians = (iDegrees * Math.PI / 180),
        iDX = (oPos.left - iCenterX),
        iDY = (oPos.top - iCenterY)
    ;

    return {
        x: iCenterX + (iDX * Math.cos(iRadians)) - (iDY * Math.sin(iRadians)),
        y: iCenterY + (iDX * Math.sin(iRadians)) + (iDY * Math.cos(iRadians))
    };
};

eg:

Where does the top-left corner of <div id='element'>...</div> end up when rotated by 45 degrees around it's bottom-left corner?

var oXY = XYRotatesTo($('#element'), 45, 0, 0, 0, 100);

Upvotes: 0

hugomg
hugomg

Reputation: 69924

We can model the trajectory of a single point by

(x',y') = (xc + r cos(theta + theta0), yc + r sin(theta + theta0))

where

(x', y') = new position
(xc, yc) = center point things rotate around
(x, y) = initial point
r = distance between (x,y) and (xc, yc)
theta = counterclockwise rotation, in radians
theta0 = initial rotation of (x,y), in radians

Our initial point tells us that

r sin(theta0) = (y - yc) 
r cos(theta0) = (x - xc)

By the power of trigonomerty:

r cos(theta + theta0) =
r cos(theta)cos(theta0) - r sin(theta)sin(theta0) = 
cos(theta)(x - xc) - sin(theta)(y - yc)

and

r sin(theta + theta0) = 
r sin(theta)cos(theta0) + r cos(theta)sint(theta0)
sin(theta)(x - xc) + cos(theta)(y - yc)

Therefore, given

  1. The center point (xc, yc) that stuff is rotating around
  2. The point to track (x, y) - (your rectangle corner)
  3. A rotation theta, in radians

The new position of the point will be:

x' = xc + dx cos(theta) - dy sin(theta)
y' = yc + dx sin(theta) + dy cos(theta)

with dx and dy given by

dx = x - xc
dy = y - yc    

Upvotes: 6

Related Questions