Why is this not a star? Using Matrix Manipulation

Can anyone tell me why this doesn’t draw a star with 5 equal sides? I can’t figure out what concept I have wrong.
I’m using the implementation from Mesa3D.

Here’s basically what I’m doing:


VGubyte close[] = {VG_CLOSE_PATH};
VGubyte cmds[] = {VG_LINE_TO_REL};
VGfloat coords[] = {200.0, 0.0};
VGint imgWidth = 800; VGint imgHeight = 800;

VGImage star = vgCreatePath(...);
VGImage line = vgCreatePath(...);

vgAppendPathData(line, 1, cmds, coords);

vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
vgLoadIdentity();

for(i=0; i<4; i++)
{
  vgTransformPath(star, line);
  vgRotate(-144.0);
}

vgAppendPathData(star, 1, close, coords);

...

vgLoadIdentity();
vgTranslate(imgWidth/2, imgHeight/2);
vgDrawPath(star, VG_STROKE_PATH);

and I’m getting the attached image (why are the lengths messed up?):

Didn’t know Mesa had a OpenVG implementation. Have they had it long? Their web page doesn’t mention it.

If I had to guess, I’d say it’s because your point of rotation is on one of the points of the star. Try initializing your star path with a VG_MOVE_TO_ABS to point (-100,0). Is there a reason for this peculiar way of creating a star rather than just inputing the coordinates?

I suppose it could be a bug in the driver - rarely used functions like vgTransformPath() when appending relative coordinates (especially for smooth curves) are some of the places I’d expect bugs if the driver was not tested properly. Did you try the Khronos reference implementation as a cross reference? Comparing to the reference implementation is the best way the best way to determine whether the API is working correctly or not when you suspect a driver bug.

Zack Rusin added his implementation to Mesa in May. Try /openvg.html for the page on their site.

Ok, wow.
I tried my code on Shiva and was getting the same thing, thought it was me.
Then I moved to Khronos’s implementation and I got what I was expecting. Hot dog!

So the bug that seems to be present in both Mesa and Shiva is one of the following:
The last point of the previous segment (ox, oy) isn’t properly converted when the surface is rotated.
OR
VG_LINE_TO_REL is treated like VG_LINE_TO_ABS.

Example:
Let’s say I have the command: VG_LINE_TO_REL 100.0, 0.0
With the identity matrix, the location (100, 0) is to the right of the origin.
First execution of the command will draw a horizontal line along the x-axis. This should cause (ox, oy) = (100, 0).
If I rotate 90 degrees CW, then the location (100, 0) is now above the origin (along the y-axis).
THEREFORE, (ox, oy) should be converted to its new value (0, -100).
When I append the command again, what should happen is (0, -100) + (100, 0) = (100, -100) (which would draw a vertical line with a 90 degree angle to the first drawn horizontal line).
However, the line is drawn from the end of the first line to the absolute location (100, 0) (which is now above the origin) thus creating a slanted line. So either (ox, oy) isn’t being converted correctly or VG_LINE_TO_REL is always treated like and ABS command.

If you don’t follow, I can make pictures.

Couldn’t find edit button: I meant to say “rotate 90 degrees CCW” instead of “rotate 90 degrees CW”.

You only calculate 4 corners:

for(i=0; i<4; i++)

And then you start drawing in the middle of the canvas, not at one corner of the star:

vgTranslate(imgWidth/2, imgHeight/2);

Happens to us all :wink:

Nope, it was bug.

I calculate 4 sides and then add a CLOSE_PATH command for the fifth.

The translation is to move it away from the origin (the bottom left corner) into the middle. vgTranslate is correct, so it correctly adjusts all the coordinates (though they may be wrong from the get go).

See: http://www.nabble.com/OpenVG-Bug%3A-Eit … 68115.html