# SVG and matrices

This topic is 3700 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am trying to implement some support for SVG in my game, actually it will only support rectangles as that's all i need. Anyways, I don't really understand matrices so I'm probably doing something terribly wrong. Anyways, this is the relevant code:
	float x, y, height, width, opacity;

if (rect->QueryFloatAttribute("x", &x) != TIXML_SUCCESS)
return;

if (rect->QueryFloatAttribute("y", &y) != TIXML_SUCCESS)
return;

if (rect->QueryFloatAttribute("width", &width) != TIXML_SUCCESS)
return;

if (rect->QueryFloatAttribute("height", &height) != TIXML_SUCCESS)
return;

if (rect->QueryFloatAttribute("opacity", &opacity) != TIXML_SUCCESS)
opacity = 0.5;

boost::numeric::ublas::vector<float> bottom_left(3);
// Assign x
bottom_left[0] = x;
// Assign y
bottom_left[1] = y;
// Assign z
bottom_left[2] = 0.0;

boost::numeric::ublas::vector<float> bottom_right(3);
bottom_right[0] = x + width;
bottom_right[1] = y;
bottom_right[2] = 0.0;

boost::numeric::ublas::vector<float> top_left(3);
top_left[0] = x;
top_left[1] = y + height;
top_left[2] = 0.0;

boost::numeric::ublas::vector<float> top_right(3);
top_right[0] = x + width;
top_right[1] = y + height;
top_right[2] = 0.0;

// transform may or may not exist
const char * transform = rect->Attribute("transform");

if (transform)
{
using boost::numeric::ublas::column_major;
boost::numeric::ublas::matrix<float> matrix(3, 3);

bool full = boost::spirit::parse(transform,
( // begin grammar
str_p("matrix(") >> real_p[ assign_a( matrix(0, 0) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(1, 0) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(0, 1) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(1, 1) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(0, 2) ) ] >> *ch_p(',') >> real_p[ assign_a( matrix(1, 2) ) ] >> ch_p(')')
), // end grammar
boost::spirit::space_p).full;

if (!full)
return;

matrix(2, 0) = 0;
matrix(2, 1) = 0;
matrix(2, 2) = 1;

bottom_left = boost::numeric::ublas::prod(matrix, bottom_left);
bottom_right = boost::numeric::ublas::prod(matrix, bottom_right);
top_left = boost::numeric::ublas::prod(matrix, top_left);
top_right = boost::numeric::ublas::prod(matrix, top_right);

/*
bottom_left = boost::numeric::ublas::prod(bottom_left, matrix);
bottom_right = boost::numeric::ublas::prod(bottom_right, matrix);
top_left = boost::numeric::ublas::prod(top_left, matrix);
top_right = boost::numeric::ublas::prod(top_right, matrix);
*/
}

boost::shared_ptr<Rectangle> rectangle(new Rectangle);
rectangle->bottom_left = toVec2(bottom_left);
rectangle->bottom_right = toVec2(bottom_right);
rectangle->top_left = toVec2(top_left);
rectangle->top_right = toVec2(top_right);

rectangles.push_back(rectangle);


I'm using boost::spirit and boost::matrix and boost::vector and TinyXML. This is how it currently looks in my engine: And this is how it should look: Note: Color is not implemented yet. The relevant svg spec about matrices is here: http://www.w3.org/TR/SVG11/coords.html#TransformMatrixDefined The used .svg file is here: http://rafb.net/p/zMYK1889.html As you can see the rectangles that doesn't use matrices look correct but those who does looks wrong. (My matrix math is probably wrong) EDIT: Um, i changed the z coord of the start vectors to 1.0 and it seems to look okay but the .svg is flipped upside down. And clues? EDIT2: I have the same base .svg orginally exported from Illustrator instead of Inkscape and it still doesn't look correct: Svg is here: http://rafb.net/p/MuGjZL59.html [Edited by - lexs on May 28, 2008 2:59:22 PM]

Noone?

##### Share on other sites
If it's flipped upside down, you're probably just using the wrong coordinate system. Just flip the Y-axis. And yes, the 'Z' coordinates do need to be set to 1, otherwise the coordinates do not get translated, only rotated.

##### Share on other sites
It renders correctly now (I was not aware that the svg spec didn't require x and y coords).
But it's still upside down. Simply flipping the Y will give wrong results:

This image is how it looks now, with the green dot being (0,0) in the svg image. It is correctly situated and the lower left corner. If I flip the Y axis it will instead be in the top left corner.

##### Share on other sites
Then maybe you're reading the matrix wrong. Try placing an object that's not rotated by 45 degrees into the SVG. E.g. rotate by 25 degrees. If it renders at a wrong angle, then you're reading the elements of the matrix into incorrect locations.

##### Share on other sites
Made a .svg with two rectangles rotated by 25 deg and -25 deg:

Seems to render correctly, just upside down :)

##### Share on other sites
So only the rectangles are upside down, even the ones that don't have the transform attribute? But the green dot isn't? How does the SVG differ for the two?

##### Share on other sites
Yeah. The dot I render manually. I think I have something wrong in my Rect->VBO code (not posted). Will check it and report back ;)

##### Share on other sites
Damn, you were right from the beginning. The origin in SVG is top left so flipping Y is correct.
Thanks!

##### Share on other sites
It seems that the SVG origin is in the top-left corner, so even your green dot is upside down. Viewport

1. 1
Rutin
19
2. 2
3. 3
JoeJ
15
4. 4
5. 5

• 21
• 19
• 11
• 13
• 17
• ### Forum Statistics

• Total Topics
631697
• Total Posts
3001764
×