15,031,962 members
Articles / Desktop Programming / WPF
Alternative
Article
Posted 8 Jul 2012

13.5K views
14 bookmarked

# GraphDisplay: A Bezier based control for graphing functions and curves

Rate me:
5.00/5 (4 votes)
8 Jul 2012CPOL1 min read
This is an alternative for "GraphDisplay: a Bezier based control for graphing functions and curves"

## Introduction

I really like this approach and intend to use the code as a library in one of my projects which will mostly display polar curves so I thought that adding an alternative polar grid would be useful.

I hope that this is an acceptable very minor addition to an excellent project.

## Using the code

I added a several new functions to the `GraphDisplay` class  following the style of the author, specifically

1. A function `AddPolarGrid` to build the grid from circular and radial rules
2. A function` AddCircularRule` to add a Circular rule to the display
3. A function `AddRadialRule` to add a Radial rule to the display
4. I also renamed the original `AddGrid` function to AddRectanglarGrid
C#
```/// <summary>
/// Adds a polar grid to the GraphDisplay
/// </summary>
/// <param name="x" />The r Size of the grid radius in graphed units
/// <param name="y" />The a Size of the grid angle in graphed units
/// <param name="style" />The style information for the graph

public void AddPolarGrid(double r, double a, GraphStyle style)
{
int rLeft = (int)Math.Ceiling(Math.Abs(XRight) / r);
int rRight = (int)Math.Ceiling(Math.Abs(XLeft) / r);
int rHoriz = Math.Max(rLeft,rRight);
int rTop = (int)Math.Ceiling(Math.Abs(YTop) / r);
int rBot = (int)Math.Ceiling(Math.Abs(YBottom) / r);
int rVert = Math.Max(rTop,rBot);
int imax = Math.Max(rHoriz,rVert);
double rmax = r * (imax + 1);

for (int i = 0; i < imax + 1; i++)
{
AddCircularRule((i + 1)* r, style);
}

for (double aa = 0; aa <= 360 ; aa += a)
{
double rad = aa * Math.PI / 180.0;
double cos = Math.Cos(rad);
double sin = Math.Sin(rad);
Point orig = new Point(r * cos, r * sin);
Point end = new Point(rmax * cos, rmax * sin );
AddRadialRule(orig,end,style);
}
}

/// <summary>
/// Adds a Circular rule at the specified radial value
/// </summary>
/// <param name="r" />The radius of the rule
/// <param name="style" />The Graphstyle for the rule

public void AddCircularRule(double r, GraphStyle style)
{
Path p = new Path();
EllipseGeometry eg = new EllipseGeometry();
eg.Center = new Point( mXTransform.Value(0), mYTransform.Value(0));
eg.RadiusX =  mXTransform.Value(r) - eg.Center.X;
eg.RadiusY =  mYTransform.Value(r) - eg.Center.Y;
p.Data = eg;
p.Fill = style.Fill;
p.Stroke = style.Stroke;
p.StrokeThickness = style.Thickness;
DisplayCanvas.Children.Add(p);
}

/// <summary>
/// Adds a Radial rule from centre to the specified X,Y value
/// </summary>
/// <param name="x" />The X position for the rule
/// <param name="y" />The Y position for the rule
/// <param name="style" />The Graphstyle for the rule

public void AddRadialRule(Point orig, Point end, GraphStyle style)
{
Path p = new Path();
LineGeometry lg = new LineGeometry();
lg.StartPoint = new Point(mXTransform.Value(orig.X), mYTransform.Value(orig.Y));
lg.EndPoint = new Point(mXTransform.Value(end.X), mYTransform.Value(end.Y));
p.Data = lg;
p.Fill = style.Fill;
p.Stroke = style.Stroke;
p.StrokeThickness = style.Thickness;
DisplayCanvas.Children.Add(p);
}```

I also made some simple xaml changes to `RoseCurveDisplay`, I added a `checkbox` to the Decorations Expander in `RoseCurveDisplay` and gave each checkbox a name to allow the polar grid to be selected.

XML
```<expander removed="{StaticResource HeaderBrush}" isexpanded="True" name="exDecorations"
dockpanel.dock="Top" grid.column="1">
...
<grid removed="{StaticResource InteriorBrush}">
<stackpanel>
<checkbox unchecked="checkBoxChanged" checked="checkBoxChanged"
margin="22,0,0,0" name="chkShowGrid">Show Grid</checkbox>
<checkbox unchecked="checkBoxChanged" checked="checkBoxChanged"
margin="22,0,0,0" name="chkGridPolar">Polar Grid</checkbox>

...

<textblock x:name="GridXWidth">X width</textblock>
...

<textblock grid.row="1" x:name="GridYWidth">Y width</textblock>

</stackpanel>
</grid>
</expander>```

and added code expose the new checkbox status as a property, and modified the `RoseCurveDisplay.checkBoxChanged` event handler so that the text of the two labels describing the two data items required by the grid would be dependent on the selected grid type.

C#
```public bool IsGridPolar
{
get { return (bool)chkGridPolar.IsChecked; }
set { chkGridPolar.IsChecked = value; }
}

private void checkBoxChanged(object sender, RoutedEventArgs e)
{
// change text to reflect this
if (IsGridPolar)
{
GridXWidth.Text = "R width";
GridYWidth.Text = "Angle";
}
else
{
GridXWidth.Text = "X width";
GridYWidth.Text = "Y width";
}

// original code
if (GraphChanged != null)
{
GraphChanged(this, new EventArgs());
}
}```

Finally I altered `MainWindow.DisplayRoseCurve `to display the correct grid.

C#
```public void DisplayRoseCurve()
{
...

if (rcd.IsGridVisible)
{
if (!rcd.IsGridPolar)
this.gDisplay.AddRectangularGrid(rcd.GridX, rcd.GridY, gridStyle);
else
this.gDisplay.AddPolarGrid(rcd.GridX, rcd.GridY, gridStyle);

...
}```

## Points of Interest

You could also add code into checkBoxChanged to alter the slider ranges for the GridWidth values to be dependent on the grid type. For example you may wish to make the slider range values for the Y values (which are used to give the angular width for a polar grid) go from 1 to 180 degrees.

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 Retired United Kingdom
I have been programming since the Apple 2 was produced, which is quite a long time now. Favorite language is c#

## Comments and Discussions

 -- There are no messages in this forum --