     Home Search   What's New Index Books Links Q & A Newsletter Banners   Feedback Tip Jar     MSDN Visual Basic Community   Title Draw contour plots (level curves) for a function with known derivatives contour, level curve, plot Graphics For each contour value:

• Start at a probe point. Follow the gradient until you find a point on the contour.
• Move perpendicular to the gradient to find the next probe point. Follow the gradient to find the next point on the contour.
• Repeat until the curve leaves the area of interest or the curve connects with itself.

This program has several shortcomings. Let me know if you get simple solutions for these.

• It can get stuck if it reaches a point with zero gradient (a saddle or local extreme). The program could use a nearby random point to get unstuck. These points often have more than one curve passing through them so it may be better to pick multiple probe points rather than to pick one at random.
• It does not find all contours with the same value if there is more than one. The program must give it different initial probe points so it finds them all. The program could search the area. For example, search every 0.1 units in the X and Y directions. It would need a method for telling when it found a curve it had already found. Perhaps an array indicating that the square (X, Y) already had a curve of the target value in it.
• It does not avoid problem areas. For example, it may try to evaluate X / Y where Y = 0.
• It does not follow a contour that leaves the area of interest in both directions. For example, if a curve starts at (1, 1) and moves to the left out of the area, the program should start again at (1, 1) and follow the curve to the right. This would be easy to do.

```' Return F(X, Y).
Private Function F(ByVal X As Single, ByVal Y As Single) As _
Single
F = X * X * X * X - 2 * X * X + Y * Y
End Function

' Return the partial derivative of dF/dX.
Private Function dFdX(ByVal X As Single, ByVal Y As Single) _
As Single
dFdX = 4 * X * X * X - 4 * X
End Function

' Return the partial derivative of dF/dY.
Private Function dFdY(ByVal X As Single, ByVal Y As Single) _
As Single
dFdY = 2 * Y
End Function

' Find a point on the curve close to this one.
Private Sub FindPointOnCurve(ByRef X As Single, ByRef Y As _
Single, ByVal level As Single, Optional ByVal start_x _
As Single = 0.1, Optional ByVal start_y As Single = _
0.2, Optional ByVal tolerance As Single = 0.01, _
Optional ByVal initial_delta As Single = 0.1)
Dim dZ As Single
Dim dist As Single
Dim delta As Single
Dim F_XY As Single
Dim dx As Single
Dim dy As Single
Dim direction As Integer

' Start at the starting point.
X = start_x
Y = start_y
delta = initial_delta

' Repeat until we have a decent solution.
Do
' See how far off we are.
F_XY = F(X, Y)
dZ = level - F_XY
If Abs(dZ) < tolerance Then Exit Do

' See if we are switching directions.
If Sgn(dZ) <> direction Then
' We are switching directions. Decrease delta.
delta = delta / 2
direction = Sgn(dZ)
End If

If Abs(dx) + Abs(dy) < 0.001 Then Exit Do

' Move in the right direction.
X = X + dx * delta * direction
Y = Y + dy * delta * direction
'Debug.Print X; Y
Loop
End Sub

' Return the gradient at this point.
Private Sub Gradient(ByVal X As Single, ByVal Y As Single, _
ByRef dx As Single, ByRef dy As Single)
Dim dist As Single

dx = dFdX(X, Y)
dy = dFdY(X, Y)
dist = Sqr(dx * dx + dy * dy)
If Abs(dist) < 0.0001 Then
dx = 0
dy = 0
Else
dx = dx / dist
dy = dy / dist
End If
End Sub

' Plot the level curve F(X, Y) = level.
Private Sub PlotLevelCurve(ByVal pic As PictureBox, ByVal _
level As Single, ByVal xmin As Single, ByVal xmax As _
Single, ByVal ymin As Single, ByVal ymax As Single, _
Optional step_size As Single = 0.1, Optional ByVal _
start_x As Single = 1#, Optional ByVal start_y As _
Single = 1#, Optional ByVal tolerance As Single = 0.02)
#Const SHOW_TICS = False

Dim num_points As Integer
Dim X0 As Single
Dim Y0 As Single
Dim X As Single
Dim Y As Single
Dim dx As Single
Dim dy As Single

' Find a point (X0, Y0) on the level curve.
FindPointOnCurve X0, Y0, level, start_x, start_y, _
tolerance

' Start here.
pic.CurrentX = X0
pic.CurrentY = Y0
num_points = 1

' Start following the level curve.
X = X0
Y = Y0
Do
' Find the next point along the curve.
If Abs(dx) + Abs(dy) < 0.001 Then Exit Do
X = X + dy * step_size
Y = Y - dx * step_size
FindPointOnCurve X, Y, level, X, Y, tolerance

' Draw to this point.
pic.Line -(X, Y)
#If SHOW_TICS Then
pic.Line -Step(dx * 0.1, dy * 0.1)
pic.Line -Step(-dx * 0.1, -dy * 0.1)
#End If
num_points = num_points + 1

' See if the point is outside the drawing area.
If X < xmin Or X > xmax Or _
Y < ymin Or Y > ymax _
Then Exit Do

' If we have gone at least 4 points, see if this
' is where we started.
If num_points >= 4 Then
If Sqr((X0 - X) * (X0 - X) + (Y0 - Y) * (Y0 - _
Y)) <= step_size * 1.1 Then
pic.Line -(X0, Y0)
Exit Do
End If
End If
Loop
End Sub```

For more information on graphics programming in Visual Basic, see my book Visual Basic Graphics Programming.  Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.  Updated 