Discussion:
Best way to get the the bbox of an object with respect to its transformations?
Jake B
2007-09-10 00:28:25 UTC
Permalink
Hello, I was wondering, is there was a simple way to calculate the bounding
box of an SVG element with respect to its transformations? The getBBox
method does not seem to take transformations into account.
I'm using the transform attribute because it seems to be the easiest and
most elegant way to translate a group of
elements. However, it is definitely necessary for me
to get the bounding box of the group with respect to its
transformations so that it is locatable within the SVG viewport.
If there is not an easy way to get the bounding box of an element with
respect to its transform, it seems like there are only two alternatives:
to make a newer, smarter getBBox method that does take transforms into
account, or to not use translate, instead recursively changing the
coordinates of every
member of a group and its children. However, neither of these seems like a
very pretty solution, so I am somewhat stuck...
I would greatly appreciate any guidance anyone can provide. Thanks.

Jake
t***@kodak.com
2007-09-12 10:55:15 UTC
Permalink
Hi Jake,
Post by Jake B
I was wondering, is there was a simple way to calculate the
bounding box of an SVG element with respect to its transformations?
The simple question here is it's bounding box in what coordinate
system? The most common requests are either the root of the SVG
tree (the root SVG elements local coordinate system), and screen pixels.
Post by Jake B
The getBBox method does not seem to take transformations into account.
Correct getBBox returns the bounding box in the local coordinate
system of the element. What you need to do is take that bbox and
map it to your desired coordinate system.

SVG provides fairly good methods for doing that. The two methods
that you might need to use are: getScreenCTM and getTransformToElement.
You can use these to get the Affine transform from the local coordinate
system of the element to the screen or any other element's local
coordinate system respectively.

Once you have that transform you can use code like (this is js
but mapping it to Java is just adding types mostly):
var bbox = elem.getBBox();
var mat = elem.screenCTM(); // could also be tranformToElement
var cPt = document.getRootElement().createSVGPoint();
cPt.x = bbox.x;
cPt.y = bbox.y;
cPt = cPt.matrixTransform(mat);
// repeat for other corner points and the new bbox is
// simply the minX/minY to maxX/maxY of the four points.
Post by Jake B
I'm using the transform attribute because it seems to be the easiest
and most elegant way to translate a group of elements.
Yes, it is.
Post by Jake B
However, it is definitely necessary for me to get the bounding box
of the group with respect to its transformations so that it is
locatable within the SVG viewport.
Right.
Post by Jake B
If there is not an easy way to get the bounding
box of an element with respect to its transform, it seems like there
are only two alternatives: to make a newer, smarter getBBox method
that does take transforms into account, or to not use translate,
instead recursively changing the coordinates of every member of a
group and its children. However, neither of these seems like a very
pretty solution, so I am somewhat stuck...
I would greatly appreciate any guidance anyone can provide. Thanks.
I hope the above helps.
Jake B
2007-09-13 02:52:59 UTC
Permalink
Works great! Thank you so much for your help!

Jake
Post by t***@kodak.com
Hi Jake,
Post by Jake B
I was wondering, is there was a simple way to calculate the
bounding box of an SVG element with respect to its transformations?
The simple question here is it's bounding box in what coordinate
system? The most common requests are either the root of the SVG
tree (the root SVG elements local coordinate system), and screen pixels.
Post by Jake B
The getBBox method does not seem to take transformations into account.
Correct getBBox returns the bounding box in the local coordinate
system of the element. What you need to do is take that bbox and
map it to your desired coordinate system.
SVG provides fairly good methods for doing that. The two methods
that you might need to use are: getScreenCTM and getTransformToElement.
You can use these to get the Affine transform from the local coordinate
system of the element to the screen or any other element's local
coordinate system respectively.
Once you have that transform you can use code like (this is js
var bbox = elem.getBBox();
var mat = elem.screenCTM(); // could also be tranformToElement
var cPt = document.getRootElement().createSVGPoint();
cPt.x = bbox.x;
cPt.y = bbox.y;
cPt = cPt.matrixTransform(mat);
// repeat for other corner points and the new bbox is
// simply the minX/minY to maxX/maxY of the four points.
Post by Jake B
I'm using the transform attribute because it seems to be the easiest
and most elegant way to translate a group of elements.
Yes, it is.
Post by Jake B
However, it is definitely necessary for me to get the bounding box
of the group with respect to its transformations so that it is
locatable within the SVG viewport.
Right.
Post by Jake B
If there is not an easy way to get the bounding
box of an element with respect to its transform, it seems like there
are only two alternatives: to make a newer, smarter getBBox method
that does take transforms into account, or to not use translate,
instead recursively changing the coordinates of every member of a
group and its children. However, neither of these seems like a very
pretty solution, so I am somewhat stuck...
I would greatly appreciate any guidance anyone can provide. Thanks.
I hope the above helps.
---------------------------------------------------------------------
Jake B
2007-09-22 02:27:06 UTC
Permalink
Quick follow-up question to this. I believe that getScreenCTM returns the
transformation matrix mapping user coordinates to the coordinates of the
top-level viewport. If the element is inside of a nested viewport, is there
a way to retrieve the transformation matrix to translate user coordinates
into the nested viewport coordinate system?
Thanks again for your help.

Jake
Post by Jake B
Works great! Thank you so much for your help!
Jake
Post by t***@kodak.com
Hi Jake,
Post by Jake B
I was wondering, is there was a simple way to calculate the
bounding box of an SVG element with respect to its transformations?
The simple question here is it's bounding box in what coordinate
system? The most common requests are either the root of the SVG
tree (the root SVG elements local coordinate system), and screen pixels.
Post by Jake B
The getBBox method does not seem to take transformations into account.
Correct getBBox returns the bounding box in the local coordinate
system of the element. What you need to do is take that bbox and
map it to your desired coordinate system.
SVG provides fairly good methods for doing that. The two methods
that you might need to use are: getScreenCTM and getTransformToElement.
You can use these to get the Affine transform from the local coordinate
system of the element to the screen or any other element's local
coordinate system respectively.
Once you have that transform you can use code like (this is js
var bbox = elem.getBBox();
var mat = elem.screenCTM(); // could also be tranformToElement
var cPt = document.getRootElement().createSVGPoint();
cPt.x = bbox.x;
cPt.y = bbox.y;
cPt = cPt.matrixTransform(mat);
// repeat for other corner points and the new bbox is
// simply the minX/minY to maxX/maxY of the four points.
Post by Jake B
I'm using the transform attribute because it seems to be the easiest
and most elegant way to translate a group of elements.
Yes, it is.
Post by Jake B
However, it is definitely necessary for me to get the bounding box
of the group with respect to its transformations so that it is
locatable within the SVG viewport.
Right.
Post by Jake B
If there is not an easy way to get the bounding
box of an element with respect to its transform, it seems like there
are only two alternatives: to make a newer, smarter getBBox method
that does take transforms into account, or to not use translate,
instead recursively changing the coordinates of every member of a
group and its children. However, neither of these seems like a very
pretty solution, so I am somewhat stuck...
I would greatly appreciate any guidance anyone can provide. Thanks.
I hope the above helps.
---------------------------------------------------------------------
t***@kodak.com
2007-09-22 10:52:25 UTC
Permalink
Hi Jake,
Post by Jake B
Quick follow-up question to this. I believe that getScreenCTM
returns the transformation matrix mapping user coordinates to the
coordinates of the top-level viewport.
No, it returns the transform to the screen coordinate system
(screen pixels).
Post by Jake B
If the element is inside of a nested viewport, is there a way
to retrieve the transformation matrix to translate user
coordinates into the nested viewport coordinate system?
Yes, I mentioned it below, getTransformToElement(SVGElement elem).
Pass that the nested viewport element and it will give you
the transform to that element's local coordinate system.

I suggest you read about the SVGLocatable Interface in
the SVG spec:
http://www.w3.org/TR/SVG11/types.html#InterfaceSVGLocatable
Post by Jake B
Thanks again for your help.
Jake
Works great! Thank you so much for your help!
Jake
Hi Jake,
Post by Jake B
I was wondering, is there was a simple way to calculate the
bounding box of an SVG element with respect to its transformations?
The simple question here is it's bounding box in what coordinate
system? The most common requests are either the root of the SVG
tree (the root SVG elements local coordinate system), and screen pixels.
Post by Jake B
The getBBox method does not seem to take transformations into account.
Correct getBBox returns the bounding box in the local coordinate
system of the element. What you need to do is take that bbox and
map it to your desired coordinate system.
SVG provides fairly good methods for doing that. The two methods
that you might need to use are: getScreenCTM and getTransformToElement.
You can use these to get the Affine transform from the local coordinate
system of the element to the screen or any other element's local
coordinate system respectively.
Once you have that transform you can use code like (this is js
var bbox = elem.getBBox();
var mat = elem.screenCTM(); // could also be tranformToElement
var cPt = document.getRootElement().createSVGPoint();
cPt.x = bbox.x;
cPt.y = bbox.y;
cPt = cPt.matrixTransform(mat);
// repeat for other corner points and the new bbox is
// simply the minX/minY to maxX/maxY of the four points.
Post by Jake B
I'm using the transform attribute because it seems to be the easiest
and most elegant way to translate a group of elements.
Yes, it is.
Post by Jake B
However, it is definitely necessary for me to get the bounding box
of the group with respect to its transformations so that it is
locatable within the SVG viewport.
Right.
Post by Jake B
If there is not an easy way to get the bounding
box of an element with respect to its transform, it seems like there
are only two alternatives: to make a newer, smarter getBBox method
that does take transforms into account, or to not use translate,
instead recursively changing the coordinates of every member of a
group and its children. However, neither of these seems like a very
pretty solution, so I am somewhat stuck...
I would greatly appreciate any guidance anyone can provide. Thanks.
I hope the above helps.
---------------------------------------------------------------------
Jake B
2007-09-22 13:30:23 UTC
Permalink
Thank you for your help.

Jake
Post by t***@kodak.com
Hi Jake,
Post by Jake B
Quick follow-up question to this. I believe that getScreenCTM
returns the transformation matrix mapping user coordinates to the
coordinates of the top-level viewport.
No, it returns the transform to the screen coordinate system
(screen pixels).
Post by Jake B
If the element is inside of a nested viewport, is there a way
to retrieve the transformation matrix to translate user
coordinates into the nested viewport coordinate system?
Yes, I mentioned it below, getTransformToElement(SVGElement elem).
Pass that the nested viewport element and it will give you
the transform to that element's local coordinate system.
I suggest you read about the SVGLocatable Interface in
http://www.w3.org/TR/SVG11/types.html#InterfaceSVGLocatable
Post by Jake B
Thanks again for your help.
Jake
Works great! Thank you so much for your help!
Jake
Hi Jake,
Post by Jake B
I was wondering, is there was a simple way to calculate the
bounding box of an SVG element with respect to its transformations?
The simple question here is it's bounding box in what coordinate
system? The most common requests are either the root of the SVG
tree (the root SVG elements local coordinate system), and screen pixels.
Post by Jake B
The getBBox method does not seem to take transformations into account.
Correct getBBox returns the bounding box in the local coordinate
system of the element. What you need to do is take that bbox and
map it to your desired coordinate system.
SVG provides fairly good methods for doing that. The two methods
that you might need to use are: getScreenCTM and getTransformToElement.
You can use these to get the Affine transform from the local coordinate
system of the element to the screen or any other element's local
coordinate system respectively.
Once you have that transform you can use code like (this is js
var bbox = elem.getBBox();
var mat = elem.screenCTM(); // could also be tranformToElement
var cPt = document.getRootElement().createSVGPoint();
cPt.x = bbox.x;
cPt.y = bbox.y;
cPt = cPt.matrixTransform(mat);
// repeat for other corner points and the new bbox is
// simply the minX/minY to maxX/maxY of the four points.
Post by Jake B
I'm using the transform attribute because it seems to be the easiest
and most elegant way to translate a group of elements.
Yes, it is.
Post by Jake B
However, it is definitely necessary for me to get the bounding box
of the group with respect to its transformations so that it is
locatable within the SVG viewport.
Right.
Post by Jake B
If there is not an easy way to get the bounding
box of an element with respect to its transform, it seems like there
are only two alternatives: to make a newer, smarter getBBox method
that does take transforms into account, or to not use translate,
instead recursively changing the coordinates of every member of a
group and its children. However, neither of these seems like a very
pretty solution, so I am somewhat stuck...
I would greatly appreciate any guidance anyone can provide. Thanks.
I hope the above helps.
---------------------------------------------------------------------
---------------------------------------------------------------------
Loading...