11
votes

I'm trying to put resizing handles on the four corners of a rectangle, which can be dragged to resize the rectangle. What I'm having trouble with is calculating the new width, new height, and new points of the rectangle after I've dragged one of the rectangle's points.

If the rectangle were not rotated, this would obviously be very easy because the width and height would change by the same amout as the mouse's offsetX and offsetY. However, this rectangle CAN be rotated, so offsetX and offsetY don't match up to the changes in width/height.

enter image description here

In the image above, I've represented information that I already have in solid black, and information I want to find in light grey. I've tried to show how the rectangle should change if I dragged the a1 corner up and to the right.

Could anyone help me figure out how to calculate the missing information?

Thanks for any help! It's much appreciated.

--

EDIT: I've got drag start, drag move, and drag end callbacks on each handle. My current code simply gets the new point (in this example, a2). Unfortunately this simply moves the handle we're currently dragging into its new position, but obviously has no effect on the width/height of the rectangle, and the position of its other points. What I'm hoping for help figuring out is how do I calculate the new width and height, and the new position of the other points, based on this drag.

Handle Coordinates (before drag)

handles: { 
  a: { x: 11, y: 31 },
  b: { x: 44, y: 12 }, 
  c: { x: 39, y: 2 }, 
  d: { x: 6, y: 21 }
};

Callbacks:

// Save the original x and original y coordinates
// of the handle, before dragging
onDragStart: function(x, y, handle) {
  handle.data({
   ox: x,
   oy: y
  });
}

// While dragging the handle, update it's coordinates to 
// reflect its new position
onDragMove: function(dx, dy, handle) {
  handle.attr({
   x: handle.data('ox') + dx,
   y: handle.data('oy') + dy
  });
}

// Not currently using the drag end callback
onDragEnd: function(x,y,handle) {}
2
Can you show us the code snippet with what you have so far?Ehtesh Choudhury
@Shurane I've been trying to figure this out for a long time, and written a lot of code in doing so, but none of it has helped even a little so it has been thrown out. But I'll throw the little that I do have in there.Nick Budden
I would appreciate it greatly if you can put up a demonstrable example on jsfiddle.netEhtesh Choudhury
Unfortunately there's really nothing to demonstrate. I've been Googling things like "translate rectangle one coordinate" and "javascript resize rotatable handles", and "rectangle geometry" for a few days now, and have literally gotten nowhere. All I've been able to do is move the dragged handle to it's new location, but I'm not even sure where to start when it comes to calculating the new points and sides. But I will try to add as much useful information as possible into the question.Nick Budden

2 Answers

4
votes

http://en.wikipedia.org/wiki/Cartesian_coordinate_system#Distance_between_two_points gives you the method for finding the length of a1 to a2

var len=Math.sqrt(Math.pow(a2x-a1x,2)+Math.pow(a2y-a1y,2));

Then looking at the triangle formed by the intersection of the grey and black lines (Lets call that point H) and a1 and a2. You can use trigonometry to solve. So the angle formed by the line d1 to c1 with the bottom lets call that the angle of rotation(R). That means the R is equal to angle at a2 and the angle at a1 is equal to 90-R. To find the sides then you go

//line from a2 to H 
var hDif=Math.sin(R)*len;
//line from a1 to H
var wDif=Math.cos(R)*len;

You can then use these to find the new length and height. There will a few more calculations to see if you are adding or subtracting to the old width and height.

Diagram

0
votes

I have another idea:

Consider that your rectangle is rotated by 30 degress anticlockwise with respect to the origin.

When the user clicks on one of the edges or corners, do the following:

1) Let StartPt = the point where the mouse starts.
2) Get the point where the mouse moves to. Let it be EndPt.
3) Rotate each of the vertex of the Rectangle by -30 so that now it becomes an unrotated rectangle. (Do not draw the unrotated rectangle, it is for calculcation purpose only)
4) Rotate the StartPt and EndPt by -30 degrees. Calculate the change in the width and height of the rectangle when the point.
5) Add the change to the rotated vertices of the rectangle.
6) Rotate the vertices of the Rectangle by +30 degrees. Now draw the Rectangle.

https://www.experts-exchange.com/questions/24244758/How-can-let-a-user-drag-to-resize-a-rotated-rectangle.html#answer23964155