0
\$\begingroup\$

I'm facing an issue when trying to scale a rotated rectangle in a given direction.

enter image description here

In my context, the width and height of the rectangle are based on the texture size multiplied by a scale factor (one for X-horizontal and another for Y-vertical).

Basically, if a texture width is 100 and the scale-X factor is "2" the calculated width is 200, which is the double. The same goes for the height.

Right now, if I want to scale the rectangle to the left, I'm applying a scale value and at the same time I'm modifying the X position to compensate the increased scale factor (to keep the right side of the rectangle in the same position).

If there is no rotation applied, this method works nicely, but things complicate when I rotate the rectangle (in the following example 45º):

enter image description here

From what I'm understanding, this time I have to compensate the Y position as well because of the slope BUT I can't figure out the correct relation to apply an acceptable value.

Any ideas? Thanks!

\$\endgroup\$
  • 1
    \$\begingroup\$ How do you store the position of your rectangle ? Do you store the center or a corner? And is your rescaling done manually or do you ask it from a purely mathematical standpoint? \$\endgroup\$ – mmmd Aug 26 '16 at 16:36
  • \$\begingroup\$ The position is stored in a vector, it also takes a relative origin that goes from zero to one in each axis, but you can consider the center of the rectangle as the position (by default the origin is 0.5). The scale factor by default is 1 for x and y. Meaning that I need to play with the position to keep the sides fixed when trying to resize just one side. The scaling is done by the mouse with the visual points that can be seen in the images. Thanks \$\endgroup\$ – João Alves Aug 26 '16 at 17:40
1
\$\begingroup\$

If dragging the handle is restricted in alignment with the resulting change, then you just have to move the center half of the way the square handle moved.

enter image description here

edit: added a picture

\$\endgroup\$
  • \$\begingroup\$ That only works when the rectangle isn't rotated. If there is rotation applied I need to calculate the new X and Y offset by using the direction of the rectangle (see my answer to the post). Basically I'm calculating and associating the real offset of the mouse movement to the position compensation that must be added in the object. \$\endgroup\$ – João Alves Aug 26 '16 at 18:03
  • \$\begingroup\$ Currently I'm only having some difficulties in the corner cases (top left for instance) which for some reason are getting a different slope value compared to the mouse movement vector (currently investigating the reason...).. Thanks. \$\endgroup\$ – João Alves Aug 26 '16 at 18:05
  • \$\begingroup\$ For the corner case you should probably use the scalar product. But i think explaining it fully would be outside of the scope of the original question. \$\endgroup\$ – mmmd Aug 26 '16 at 19:18
0
\$\begingroup\$

I would recommend constructing an axis aligned bounding box (AABB) around the rotated shape and checking the difference between before the shape was scaled, and then after. The delta between the previous left and the new left offset will tell you exactly how much you need to offset to compensate. This can also be applied to the top offset in the same way. Hope this helps.

\$\endgroup\$
0
\$\begingroup\$

Naturally, right after posting this I've reminded myself of a way to solve this issue using the following parametric equations to calculate the correct compensation for each axis when the rectangle is rotated:

var x = difX * Math.cos(direction);
var y = difY * Math.sin(direction);

Another problem appeared if the rotation was between 180º and 360º, as the mouse X and Y offsets should have an inverted value. For this case I've simply inverted the X and Y whenever the normalized rotation value was between those values:

 var normDirection = direction % MathHelper.PI2;
 if (Math.abs(normDirection) > MathHelper.PIo2 && Math.abs(normDirection) < MathHelper.PI + MathHelper.PIo2) {
    difX *= -1;
    difY *= -1;
 }

Also, to calculate the correct direction of the selected point which is to be dragged/positioned, I added the result of a arctangent calculation which gives the correct direction based on the mouse offset direction vector:

direction += Math.atan2(difY, difX);

Currently I'm only having some difficulties in the corner cases (top left for instance) which for some reason are getting a different slope value compared to the mouse movement vector (currently investigating the reason and will update this answer when I have some good news).

In any case, if someone has a better understanding of the problem, I'm open to more suggestions! Thanks..

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.