4

I'm trying to get the position of the actual rotated rectangle inside the bounding box.

enter image description here

The rectangle is rotated by 120deg

I'm trying to achieve the blue outline you can see here

enter image description here

I manage to get the rotation right using the matrix but I can't get the rest right.

Here is my code

let svg = document.querySelector('svg')
let overlay = document.querySelector('.overlay')
let rect = svg.children[0]

let bounds = rect.getBoundingClientRect()
let matrix = rect.getCTM()

overlay.style.top = bounds.top + 'px'
overlay.style.left = bounds.left + 'px'
overlay.style.width = bounds.width + 'px'
overlay.style.height = bounds.height + 'px'
overlay.style.transform = `matrix(${matrix.a},${matrix.b},${matrix.c},${matrix.d},0,0)`

http://jsfiddle.net/wjugqn31/67/

zaarr78
  • 467
  • 9
  • 21
  • Look at https://stackoverflow.com/questions/41898990 Is this information enough to calculate what you want? – MBo Jul 22 '18 at 07:31
  • In my case I don't know the height and with of the rectangle itself I only the bounding box width / height so I don't think it coul work in this case – zaarr78 Jul 22 '18 at 08:22
  • So known data are bounding box width / height AND rotation angle? No more? – MBo Jul 22 '18 at 08:29
  • Yes I know Boundingbox with height, width, top, left position and finally the angle (120deg). Nothing else – zaarr78 Jul 22 '18 at 08:38
  • @MBo I have the exact inverse of this question, how to get the bounds of the unrotated rectangle https://stackoverflow.com/questions/54072295/how-to-get-correct-size-and-position-of-an-object-at-an-arbitrary-rotation – 1.21 gigawatts Jan 08 '19 at 08:41

2 Answers2

9

Known data: bounding box width W, height H, rotation angle Fi
Wanted: coordinates of rotated rectangle vertices.

Unknown source rectangle size: w x h

Bounding box size for this dimension and rotation angle:

enter image description here

 H = w * Abs(Sin(Fi)) + h * Abs(Cos(Fi))
 W = w * Abs(Cos(Fi)) + h * Abs(Sin(Fi))
 denote 
 as = Abs(Sin(Fi))
 cs = Abs(Cos(Fi))

so we can solve linear equation system and get (note singularity for Pi/4 angle)

 h = (H * cs - W * as) / (cs^2 - as^2)
 w = -(H * as - W * cs) / (cs^2 - as^2)

Vertex coordinates:

 XatTopEdge = w * cs      (AE at the picture)
 YatRightEdge = h * cs    (DH)
 XatBottomEdge = h * as   (BG)
 YatLeftEdge = w * as     (AF)

Note that with given data we cannot differ between angles Fi and 90+Fi but this fact perhaps does not influence on solution (w and h will exchange each other too)

1.21 gigawatts
  • 16,517
  • 32
  • 123
  • 231
MBo
  • 77,366
  • 5
  • 53
  • 86
0

I think you could get the dimensions of the rect directly, and then apply the transform to it. In summary:

let rect = svg.children[0]
let matrix = rect.getScreenCTM()

overlay.style.top = '0'
overlay.style.left = '0'
overlay.style.width = `${rect.width.animVal.value}px`
overlay.style.height = `${rect.height.animVal.value}px`
overlay.style.transformOrigin = '0 0'
overlay.style.transform = `matrix(${matrix.a},${matrix.b},${matrix.c},${matrix.d},${matrix.e},${matrix.f})`
ewcz
  • 12,819
  • 1
  • 25
  • 47
  • I really like this solution, it works really well on simple shapes but for some cases doesn't seems to work, you can see the fiddle here http://jsfiddle.net/wjugqn31/113/ – zaarr78 Jul 22 '18 at 10:03
  • @zaarr78 that's because the bounding box is tight, while the letter itself starts at coordinates ~ `11,31`. You can [fix that](http://jsfiddle.net/wjugqn31/142/) by adding an additional offset to the transform: `matrix(${matrix.a},${matrix.b},${matrix.c},${matrix.d},${matrix.e},${matrix.f}) translate(${bbox.x}px,${bbox.y}px)` – ewcz Jul 22 '18 at 10:45