Groups | Blog | Home
all groups > dotnet drawing api > may 2006 >

dotnet drawing api : GraphicsPath.Transform to rotate around one of its points


sod0783
5/10/2006 2:52:01 PM
I'm taking a rectangle and using a Matix and GraphicsPath to draw it rotated
about its upper left corner. The problem is GraphicsPath.Transform changes
the upper left point in the path slightly, so that it is no longer the same
as m_rectanglef.Location. This is especially a problem when
m_rectanglef.Location == (0,y), and comes out (-x,y) because I can't handle
the negatives.

using (matrix = new Matrix())
{
matrix.RotateAt(m_fAngle,m_rectanglef.Location);
m_graphicspath = new
GraphicsPath(); m_graphicspath.AddRectangle(m_rectanglef);
m_graphicspath.Transform(matrix);
}

Here's example coordinates:
m_rectanglef {X = 0.0 Y = 61.0847473 Width = 136.542374 Height = 197.028244}
m_fAngle -9.889401

Before Transform:
m_graphicspath.PathPoints[0] {X = 0.0 Y = 61.0847473}

After Transform:
m_graphicspath.PathPoints[0] {X = -0.0000007710182 Y = 61.0847435}

Anyone else have this problem? Unfortunately I can't seem to find a way to
just set the path point back after Transform (PathPoints is get only). I
hate to create another GraphicsPath based off this one everytime, is that
really the only/best way?

Thanks,

Shawn

sod0783
5/11/2006 6:40:02 AM
I don't mind so much that it is off by 0.000001 pixels. The problem is this
frame represents a user selection that can be rotated, but not rotated off
its parent (PictureBox). After rotating I validate the new coordinates to
make sure they aren't off, and negative numbers no matter how small are less
than 0. If the user has the selection at Location=(0,0), and rotates it
about (0,0), Location should still be (0,0). Rounding or floating point
precision shouldn't come into play as 0*sin(a) = 0, no matter how many digits
sin(a) is to.

I've implemented the work around below, I was just thinking it would be nice
to not create/dispose an extra GraphicsPath over and over while the user is
rotating. However it doesn't seem I can change a point of an existing
GraphicsPath.

matrix.RotateAt(m_fAngle,m_pointfPivot);
graphicspathTemp = new GraphicsPath();
graphicspathTemp.AddRectangle(m_rectanglef);
graphicspathTemp.Transform(matrix);
m_graphicspath = new GraphicsPath
(
new PointF[]
{
m_pointfPivot,
graphicspathTemp.PathPoints[1],
graphicspathTemp.PathPoints[2],
graphicspathTemp.PathPoints[3]
},
graphicspathTemp.PathTypes
);
graphicspathTemp.Dispose();


[quoted text, click to view]
Göran Andersson
5/11/2006 9:04:13 AM
It's just a rounding error. The Drawing classes uses single precision
floating numbers, which have a precision of 7 digits. You simply can't
getter better precision unless you write your own Matrix object.

If the result is off by 0.000001 pixel, what is the problem really?

[quoted text, click to view]
AddThis Social Bookmark Button