Recipe 9.15. Drawing Cardinal Splines


Problem

You need a curve that goes smoothly through two or more points.

Solution

Sample code folder: Chapter 09\CardinalSplines

A Cardinal spline plots a curve through two or more points. Unlike the Bezier spline, the Cardinal spline intersects every point and does not use external control points.

Discussion

The mathematical description of the way the Cardinal spline works is beyond the scope of this book. For a more in-depth discussion and explanation of the math involved, see the links in the "See Also" section at the end of this recipe.

The following code demonstrates the Cardinal spline by collecting points as they are clicked on the face of the form. A list of the points is built up, and with each added point, the Cardinal spline is drawn anew. A button at the top of the form lets you erase all the points to start over, and a TrackBar control lets you set the tension parameter for the spline. The tension is a number ranging from 0 to 1 that is passed to the DrawCurve() method to determine the smoothness of the curve as it passes through each point. The easiest way to understand the effect of this parameter is to slide the trackBar and watch the curve change shape.

Here's the code that lets the form monitor for mouse clicks, builds the set of points, and refreshes the form to activate its Paint event:

 ' ----- Keep track of the mouse positions. Private BendPoints As New Generic.List(Of Point) Private Sub Form1_MouseClick(ByVal sender As Object, _       ByVal e As System.Windows.Forms.MouseEventArgs) _       Handles Me.MouseClick    ' ----- Add a mouse position.    BendPoints.Add(New Point(e.X, e.Y))    ' ----- Update the display.    Me.Refresh() End Sub 

The form's Paint event is where the drawing of the selected points and the spline connecting them takes place. The event fires when the form is refreshed, which is caused by calling the Refresh() method when the mouse is clicked or the trackbar is adjusted.

This code draws each plotted point in red as the user clicks it. Then, if there are two or more accumulated points, it draws the Cardinal spline using the DrawCurve() method:

 Private Sub Form1_Paint(ByVal sender As Object, _       ByVal e As System.Windows.Forms.PaintEventArgs) _       Handles Me.Paint    ' ----- Draw the spline points and line.    Dim tension As Single    Dim canvas As Graphics    Dim scanPoint As Point    Const PointSize As Integer = 7    ' ----- Determine the tension.    tension = TensionLevel.Value / TensionLevel.Maximum    LabelTension.Text = "Tension: " & tension.ToString    ' ----- Draw the points on the surface.    canvas = e.Graphics    For Each scanPoint In BendPoints       canvas.FillEllipse(Brushes.Red, _          scanPoint.X - PointSize, _          scanPoint.Y - PointSize, _          PointSize * 2, PointSize * 2)    Next scanPoint    ' ----- Draw the Cardinal spline.    If (BendPoints.Count > 1) Then       canvas.DrawCurve(Pens.Black, _          BendPoints.ToArray, tension)    End If End Sub 

When the trackbar's slider is adjusted, the form's Refresh() method is called to trigger a repaint:

 Private Sub TensionLevel_ValueChanged( _       ByVal sender As Object, ByVal e As System.EventArgs) _       Handles TensionLevel.ValueChanged    ' ----- Update the tension and display.     Me.Refresh() End Sub 

When the Reset button is clicked, the set of points is emptied, and the form is repainted to erase the points and the curve:

 Private Sub ActReset_Click(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles ActReset.Click    ' ----- Clear all points.    BendPoints.Clear()    Me.Refresh() End Sub 

Figure 9-23 shows a typical spline curve through six points with the tension set to 0.6. A lower tension results in sharp angles at the bend points, while higher tension gives a smoother curve.

Figure 9-23. Cardinal splines travel through all given points


See Also

See http://www.ibiblio.org/e-notes/Splines/Cardinal.htm and http://en.wikipedia.org/wiki/Cardinal_spline for more information on Cardinal splines.




Visual Basic 2005 Cookbook(c) Solutions for VB 2005 Programmers
Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))
ISBN: 0596101775
EAN: 2147483647
Year: 2006
Pages: 400

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net