Friday, December 30, 2011

Drawing tool story: Drawing a sine or cosine curve

Introduction

I am posting a series of article of where I am demonstrating the building of a basic drawing tool. If you are interesting in reading the previous post you can read here

Today I am going to show you guys how to draw a sine or cosine curve, Bellow I have shared a screenshot to let the user know what I am up to. In the bellow drew 9 sine curve on various values for xmin and ymin.

image

I have putdown the code in a single class named “CustomLine” the whole code is given bellow and no need farther explanation, as the class is pretty simple and any one can understand it quickly. If anyone need any explanation please drop a comment, I would more than happy to edit the post to add explanation section.

CustomLine code listing

public class CustomLine
{
private double xmax = 6.5;
private double ymax = 1.1;
private Polyline _pl;
private readonly Canvas _graphControl;

public CustomLine(Canvas graphControl)
{
Ymin = -1.1;
_graphControl = graphControl;
_graphControl.SizeChanged += GraphControlSizeChanged;
Init();
_pl = new Polyline();
}

public bool IsCoSine { get; set; }

public bool Autoscale { get; set; }

public SolidColorBrush Stroke { get; set; }

public List<Point> CurvePoints { get; set; }

public double StrokeThickness { get; set; }

public double Width { get; set; }

public DoubleCollection StrokeDashArray { get; set; }

public int PointLength { get; set; }

public int StartLocation { get; set; }

public double Xmin { get; set; }

public double Ymin { get; set; }

public double Opacity { get; set; }

public bool ShowEffect { get; set; }

public Effect LineEffect { get; set; }

#region Private Functions

private void GraphControlSizeChanged(object sender, SizeChangedEventArgs e)
{
if (Autoscale)
{
CurvePoints.Clear();
DrawSine();
}
}

private void DrawLine()
{
if (IsCoSine == false)
{
DrawSine();
}
else
{
DrawCosine();
}
}

private void Init()
{
CurvePoints = new List<Point>();
Stroke = Brushes.Black;
Width = GetGraphWidth();
StrokeThickness = 2;
StrokeDashArray = null;
PointLength = 70;
StartLocation = 1;
Xmin = 0.1;
Opacity = 1;
ShowEffect = true;
LineEffect = new BlurEffect(){Radius = 2};
}

private void DrawCosine()
{
if (_pl != null)
_graphControl.Children.Remove(_pl);

for (var i = StartLocation; i < PointLength; i++)
{
var x = i / 5.0;
var y = Math.Cos(x);
var curvePoint = GetCurvePoint(new Point(x, y));
CurvePoints.Add(curvePoint);
}

if (_pl != null)
{
_pl.Width = GetGraphWidth();
_pl.Stroke = Stroke;
if (ShowEffect)
{
_pl.Effect = LineEffect;
}
_pl.Opacity = Opacity;
_pl.Points = new PointCollection(CurvePoints);
_graphControl.Children.Add(_pl);
}
}

private void DrawSine()
{
if (_pl != null)
_graphControl.Children.Remove(_pl);

for (var i = StartLocation; i < PointLength; i++)
{
var x = i / 5.0;
var y = Math.Sin(x);
var curvePoint = GetCurvePoint(new Point(x, y));
CurvePoints.Add(curvePoint);
}

if (_pl != null)
{
_pl.Width = GetGraphWidth();
_pl.Stroke = Stroke;
if (ShowEffect)
{
_pl.Effect = LineEffect;
}
_pl.Opacity = Opacity;
_pl.Points = new PointCollection(CurvePoints);
_graphControl.Children.Add(_pl);
}
}

private Point GetCurvePoint(Point pt)
{
var x = (pt.X - Xmin) * GetGraphWidth() / (xmax - Xmin);
var y = GetGraphHeight() - (pt.Y - Ymin) * GetGraphHeight() / (ymax - Ymin);
return new Point { X = x, Y = y };
}

private double GetGraphHeight()
{
return _graphControl.ActualHeight;
}

private double GetGraphWidth()
{
return _graphControl.ActualWidth;
}

#endregion

public void Draw()
{
DrawLine();
}
}


customline uses


Bellow the uses is given, note that I have used a canvas as graph control where any drawing surface can be used, but I feel comfortable as it uses basic functionalities of a drawing surface.


private void DrawPoliLineClick(object sender, RoutedEventArgs e)
{
var line = new CustomLine(GraphControl)
{
Stroke = new SolidColorBrush(Colors.Black),
Xmin = _xmin, Ymin = _ymin ,Opacity = 0.5
};
line.Draw();
_xmin += 0.2;
_ymin += -0.1;
}


Summery


In this short article we have seen how we can use a sine wave or cosine wave curve in WPF. Hope this would help someone some day. I would continue to list lots of drawing and interesting stuff regarding WPF drawing both in 2D and 3D in future post. Until next time bye bye.

No comments:

Post a Comment