zaarr78
zaarr78

Reputation: 477

Get bounds of rotated rectangle

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/

Upvotes: 4

Views: 4454

Answers (2)

MBo
MBo

Reputation: 80287

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)

Upvotes: 9

ewcz
ewcz

Reputation: 13097

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})`

Upvotes: 0

Related Questions