1
votes

I am trying to apply a transformation on a rectangle within another rectangle.... and having quite a bit of difficulty. Here is an example of what I am trying to achieve, the rotation will always be in increments of 90 degrees:

enter image description here

I have the bottom left X/Y, width, and height of both the outer and inner rectangles.... I'm trying to calculate these same values for the transformed inner rectangle.

My attempt can be found below, I tried rotating all 4 corners around the center of the large rect then put them back together as a rect. This may not work because the large rect width/height changes during the rotation. Does anyone know of a formula to accomplish this? If someone could point me to some good resource that would be fantastic.

My Code:

Vector2 center = new Vector2(largeRectWidth / 2.0f, largeRectHeight / 2.0f);

Rect innerRectRotated = RotateRectangleAroundPivot(innerRect, center, this.Rotation);

public static Rect RotateRectangleAroundPivot(Rect rect,
                                              Vector2 pivot,
                                              float rotation)
{
    Vector2 leftTop = new Vector2(rect.x, rect.y + rect.height);
    Vector2 rightTop = new Vector2(rect.x + rect.width, rect.y + rect.height);
    Vector2 leftBottom = new Vector2(rect.x, rect.y);
    Vector2 rightBottom = new Vector2(rect.x + rect.width, rect.y);

    leftTop = RotatePointAroundPivot(leftTop, pivot, rotation);
    rightTop = RotatePointAroundPivot(rightTop, pivot, rotation);
    leftBottom = RotatePointAroundPivot(leftBottom, pivot, rotation);
    rightBottom = RotatePointAroundPivot(rightBottom, pivot, rotation);

    Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop),
                              Vector2.Min(leftBottom, rightBottom));
    Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop),
                              Vector2.Max(leftBottom, rightBottom));

    return new Rect(min.x, min.y, (max.x - min.x), (max.y - min.y));
}

public static Vector2 RotatePointAroundPivot(Vector2 point, Vector2 pivot, float angle)
{
    angle = angle * Mathf.PI / 180.0f;
    return new Vector2((float)(Math.Cos(angle) * (point.x - pivot.x) - Math.Sin(angle) * (point.y - pivot.y) + pivot.x), (float)(Math.Sin(angle) * (point.x - pivot.x) + Math.Cos(angle) * (point.y - pivot.y) + pivot.y));
}
1

1 Answers

0
votes

well in 2D for 90deg rotations you do not need any trigonometry

  • use this instead:
  • input point (x,y) is rotated by 90deg like this:
  • xx=y; yy=-x;
  • the other direction is:
  • xx=-y; yy=x;
  • which formula is CW and CCW depends on your coordinate system
  • booth rotates point around point (0,0) by 90deg
  • so if you want to rotate by any other point just shift the points before and after ...

so do it like this:

  1. translate point to your center of rotation

    • x-=x0; y-=y0;
  2. rotate left or right

    • for example:
    • aa=x; bb=y; x=-bb; y=+aa;
  3. translate point back

    • x+=x0; y+=y0;
  4. now the x,y holds the rotated point

[notes]

  • if you want the center of rotation to be the middle of rectangle
  • then the x0,y0 is average point ...
  • so if rectangle is defined as x1,y1,...,x4,y4
  • then x0=(x1+x2+x3+x4)/4.0; and y0=(y1+y2+y3+y4)/4.0;