B
Bruce Schechter
I am creating a custom control, "Graph", which will draw a set of graphs of
data on a normal Cartesian (x,y) coordinate system. The max and min values
of both x and y and determined on the fly based on the specific range of
data being plotted.
I am (for my first time) using GDI+ to do the World coordinates to screen
coordinates transformation using the Graphics.Transform method via a Matrix
class object I built via one of the Matrix class constructors.
(Specifically, I'm using the constructor of the form: Matrix(RectangleF,
PointF[]); )
When I first mocked up the code, I got no points drawn in my control. Ater
hours of debugging, I discovered that the control is trying to plot points
which are basically correct, except that each y coordinate is the negative
of what it should be. Thus, no points were displayed in the custom control
but rather were off-scale in the negative direction.
As a "work around", I found that I can just scale the transformation matrix
by -1 in the y direction, and then plotted points are correct. But I really
want to get to the bottom of my problem so that I can prevent other related
problems in the future.
Specifically, I would appreciate a pointer to where is the problem in my
code below.
Thanks,
Bruce
----------------------------------------------------------------
// Per the online documentation of the Matrix class constructor....
// PointF[] below is an array of three PointF structures that represents the
points
// of a parallelogram to which the upper-left, upper-right, and lower-left
corners
// of the rectangle (rectFWorld) is to be transformed. The lower-right
// corner of the parallelogram is implied by the first three corners.....
// W == world coordinates.
// These four variables determine the range of data to be plotted on each
axis.
float XWMin, YWMin, XWMax, YWMax;
XWMin = bizLayer.XMin;
XWMax = bizLayer.XMax;
YWMin = bizLayer.YMin;
YWMax = bizLayer.YMax;
rectFWorld = new RectangleF( XWMin, YWMax, XWMax-XWMin, YWMax-YWMin );
// Coordinates in pixels, which define the boundary of
// this Graph control instance.... These will construct a PointF[] below...
float XMin, YMin, XMax, YMax;
XMin = 0;
XMax = this.Width;
YMin = this.Height; // Since (0,0) is in upper left on a control.
YMax = 0;
Matrix matrix = new Matrix( rectFWorld,
new PointF[] { new PointF( XMin, YMax ),
new PointF( XMax, YMax ), new PointF( XMin, YMin ) } );
e.Graphics.Transform = matrix;
float penWidth = (YWMax-YWMin)/this.Height;
pen = new Pen( System.Drawing.Brushes.Gray, penWidth );
// Draw X axis...
path = new GraphicsPath();
path.AddLine( XWMin, 0f, XWMax, 0f );
e.Graphics.DrawPath( pen, path );
// Draw Y axis...
path.Reset();
path.AddLine( 0f, YWMin, 0f, YWMax );
e.Graphics.DrawPath( pen, path );
pen.Dispose();
etc...
data on a normal Cartesian (x,y) coordinate system. The max and min values
of both x and y and determined on the fly based on the specific range of
data being plotted.
I am (for my first time) using GDI+ to do the World coordinates to screen
coordinates transformation using the Graphics.Transform method via a Matrix
class object I built via one of the Matrix class constructors.
(Specifically, I'm using the constructor of the form: Matrix(RectangleF,
PointF[]); )
When I first mocked up the code, I got no points drawn in my control. Ater
hours of debugging, I discovered that the control is trying to plot points
which are basically correct, except that each y coordinate is the negative
of what it should be. Thus, no points were displayed in the custom control
but rather were off-scale in the negative direction.
As a "work around", I found that I can just scale the transformation matrix
by -1 in the y direction, and then plotted points are correct. But I really
want to get to the bottom of my problem so that I can prevent other related
problems in the future.
Specifically, I would appreciate a pointer to where is the problem in my
code below.
Thanks,
Bruce
----------------------------------------------------------------
// Per the online documentation of the Matrix class constructor....
// PointF[] below is an array of three PointF structures that represents the
points
// of a parallelogram to which the upper-left, upper-right, and lower-left
corners
// of the rectangle (rectFWorld) is to be transformed. The lower-right
// corner of the parallelogram is implied by the first three corners.....
// W == world coordinates.
// These four variables determine the range of data to be plotted on each
axis.
float XWMin, YWMin, XWMax, YWMax;
XWMin = bizLayer.XMin;
XWMax = bizLayer.XMax;
YWMin = bizLayer.YMin;
YWMax = bizLayer.YMax;
rectFWorld = new RectangleF( XWMin, YWMax, XWMax-XWMin, YWMax-YWMin );
// Coordinates in pixels, which define the boundary of
// this Graph control instance.... These will construct a PointF[] below...
float XMin, YMin, XMax, YMax;
XMin = 0;
XMax = this.Width;
YMin = this.Height; // Since (0,0) is in upper left on a control.
YMax = 0;
Matrix matrix = new Matrix( rectFWorld,
new PointF[] { new PointF( XMin, YMax ),
new PointF( XMax, YMax ), new PointF( XMin, YMin ) } );
e.Graphics.Transform = matrix;
float penWidth = (YWMax-YWMin)/this.Height;
pen = new Pen( System.Drawing.Brushes.Gray, penWidth );
// Draw X axis...
path = new GraphicsPath();
path.AddLine( XWMin, 0f, XWMax, 0f );
e.Graphics.DrawPath( pen, path );
// Draw Y axis...
path.Reset();
path.AddLine( 0f, YWMin, 0f, YWMax );
e.Graphics.DrawPath( pen, path );
pen.Dispose();
etc...