Get bounds of rotated rectangle

2020-02-14 20:30发布

问题:

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

The rectangle is rotated by 120deg

I'm trying to achieve the blue outline you can see 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/

回答1:

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:

 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)



回答2:

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