23.3.5.3 Bézier curves project

With the CurveTo method of the Paint class, you can also draw curved lines whose curvature behaviour you specify. The CurveTo method uses a third-degree Bézier curve for drawing, which is determined by 4 points. Bézier curves with a degree higher than 3 are superfluous because complex curve arcs can be composed of partial arcs of Bézier curves of 1st - 3rd degree. Interesting, well-structured information on the definition and description of Bézier curves can be found, for example, at http://www.mathepedia.de/Bezierkurven.aspx and www.de.wikipedia.org/wiki/Bezierkurve.

In → Chapter 23.3.9, an attempt is made to develop an analytical description of a 2nd order Bézier curve from the geometric definition of a 2nd degree Bézier curve - for which there is no method in the Paint class. This derivation forms the theoretical basis for part of the present project, as some 2nd degree Bézier curves are drawn using the explicit parameter equations obtained and the methods of the Paint class.

Example 1

In the first example, a third-degree Bézier curve is drawn:

B1

Figure 23.3.5.3.1: Modelled Bézier curve of the 3rd degree (4 points)

Points A and D determine the start and end points of the curve. The curvature behaviour is then determined by the position of points B and D → Figure 23.3.5.3.1. You may be surprised that only three points are specified in the documentation for the CurveTo method:

CurveTo ( X1 As Float, Y1 As Float, X2 As Float, Y2 As Float, X3 As Float, Y3 As Float )

This is correct because the current point is always understood as the starting point P0(X0|Y0) = A. This means that only the coordinates of points B, C and D are specified in the CurveTo method call.

This is the complete source code for drawing the image in → Figure 23.3.5.3.1:

[1] Public Sub PaintScriptBézier4Points()
[2]   Dim vP As Vector
[3]   
[4]   GenerateNewPicture()
[5]   SetPictureBorder()  
[6]   Paint.Begin(hPicture) 
[7]     Paint.Translate(xTranslate, yTranslate)
[8]     Paint.Scale(xScale, yScale) ' +y ▲  
[9]     DrawCoordinateSystem()
[10]      
[11] '-- Vector with 8 elements, data type: real numbers (no complex numbers)    
[12]     vP = New Vector(8, False)
[13] '-- A(30|30), B(150|250), C(400|60), D(510|210)  
[14]     vP = [30, 30, 150, 250, 400, 60, 510, 210]
[15]     Paint.Brush = Paint.Color(Color.Red)
[16]     Paint.LineWidth = 4
[17]     Paint.LineCap = Paint.LineCapRound
[18] 
[19]     Paint.MoveTo(vP[0], vP[1])    
[20]     Paint.CurveTo(vP[2], vP[3], vP[4], vP[5], vP[6], vP[7])
[21]     Paint.Stroke()
[22]     
[23] '-- Draw connecting lines A-B-C-D
[24]     Paint.Brush = Paint.Color(Color.Blue)
[25]     Paint.LineWidth = 1
[26]     Paint.Dash = [1, 1] '-- Dotted line (begin)
[27]     Paint.MoveTo(vP[0], vP[1])
[28]     Paint.LineTo(vP[2], vP[3])
[29]     Paint.LineTo(vP[4], vP[5])
[30]     Paint.LineTo(vP[6], vP[7])
[31]     Paint.Stroke()
[32]     Paint.Dash = [] '-- Dotted line (end)
[33]  
[34] '-- Draw in points A, B, C and D
[35]     Paint.Arc(vP[0], vP[1], 3)
[36]     Paint.Arc(vP[2], vP[3], 3)
[37]     Paint.Arc(vP[4], vP[5], 3)
[38]     Paint.Arc(vP[6], vP[7], 3)
[39]     Paint.Fill()
[40]     
[41] '-- Draw TEXTS
[42]     Paint.NewPath
[43]     Paint.Scale(1, -1)
[44]     Paint.Font = Font["Monospace, 11"]
[45]     Paint.Brush = Paint.Color(Color.DarkBlue)
[46]     Paint.DrawText("A", 25, -10)
[47]     Paint.DrawText("B", 145, -265)     
[48]     Paint.DrawText("C", 398, -35)
[49]     Paint.DrawText("D", 505, -225)
[50]     Paint.Scale(1, -1)    
[51]   Paint.End()
[52]   
[53] End

Comment:

Note: Certain connecting lines and the support points B and C are only drawn in the instructions from line 23 onwards to clarify the position of all points in relation to the Bézier curve. The points A, B, C and D are drawn as a circle with a very small radius. Finally, the four points are labelled - but without specifying coordinates.

Example 2

In this example, a number 2 is drawn from three Bézier curves - from two Bézier curves of the third degree and a line (Bézier curves of the first degree).

B2

Figure 23.3.5.3.2: Number 2 from three Bézier curves

The source code for the procedure PaintScriptBezierNumber2() is given in full and commented:

[1] Public Sub PaintScriptBezierNumber2()
[2]   Dim PS, P1, P2, PE As New PointF
[3]   Dim vP, vQ As Vector
[4]   Dim fYOffset As Float
[5]   
[6]   GenerateNewPicture()
[7]   SetPictureBorder()  
[8]   Paint.Begin(hPicture) 
[9]     Paint.Translate(xTranslate, yTranslate)
[10]     Paint.Scale(xScale, yScale) ' +y ▲  
[11]     DrawCoordinateSystem()
[12]   
[13] '-- Draw number 2
[14]     Paint.Scale(2, 2) ' +Zoom with a factor of 2
[15]     Paint.LineWidth = 18
[16]     fYOffset = Paint.LineWidth / 2
[17]   ' -----------------------------------------------------
[18]   ' Upper arch - red
[19]     PS.x = 60
[20]     PS.y = 90 + fYOffset
[21]     P1.x = 60
[22]     P1.y = 130 + fYOffset
[23]     P2.x = 135
[24]     P2.y = 130 + fYOffset
[25]     PE.x = 135
[26]     PE.y = 90 + fYOffset
[27]     Paint.LineCap = Paint.LineCapRound
[28]     Paint.Brush = Paint.Color(Color.Red)
[29]     Paint.MoveTo(PS.x, PS.y)
[30]     Paint.CurveTo(P1.x, P1.y, P2.x, P2.y, PE.x, PE.y)
[31]     Paint.Stroke()
[32]   ' -----------------------------------------------------    
[33]   ' Centre curve - blue
[34]     vP = New Vector
[35]     vP = [60, 0, 60, 45, 135, 45, 135, 90]
[36]     vQ = New Vector
[37]     vQ = [0, 1, 0, 1, 0, 1, 0, 1]
[38]   ' vP = [60, 0 + fYOffset, 60, 45 + fYOffset, 135, 45 + fYOffset, 135, 90 + fYOffset]
[39]     vP = vP + fYOffset * vQ
[40]     Paint.Brush = Paint.Color(Color.Blue)
[41]     Paint.MoveTo(vP[0], vP[1])    
[42]     Paint.CurveTo(vP[2], vP[3], vP[4], vP[5], vP[6], vP[7])
[43]     Paint.Stroke()
[44]   ' -----------------------------------------------------   
[45]   ' Lower curve - green - 1st degree Bezier curve (straight line)
[46]     Paint.Brush = Paint.Color(Color.Green)
[47]     Paint.MoveTo(60, 0 + fYOffset)
[48]     Paint.LineTo(135, 0 + fYOffset) ' 1st degree Bezier curve
[49]     Paint.Stroke()
[50]   Paint.End()
[51] 
[52] End

Comment:

This is what the figure 2 looks like if only one colour is used for drawing:

B3

Figure 23.3.5.3.3: Number 2 from three Bézier curves

Example 3

In this example, a graph is drawn that consists of several 3rd degree Bézier curves and other shapes (lines, circles). Points and connecting lines between the points are not drawn. Different colours are used to distinguish the individual curves. In addition to the other examples above, a text and a symbol are drawn:

B4

Figure 23.3.5.3.4: Complex graphic with Bézier curves

The source code for the third example is also given in full and then commented:

[1] Public Sub PaintScriptBezierAuto()
[2]   Dim vP As Vector
[3]   Dim P0, P1, P2, P3 As New PointF
[4]   GenerateNewPicture()
[5]   SetPictureBorder()  
[6]   Paint.Begin(hPicture) 
[7]     Paint.Translate(xTranslate, yTranslate)
[8]     Paint.Scale(xScale, yScale) ' +y ▲  
[9]     DrawCoordinateSystem()
[10]     Paint.Scale(1.3, 1.3) ' +Zoom with a factor of 1.3
[11]     
[12]   ' CAR
[13]   ' -----------------------------------------------------  
[14]   ' Front bumper       
[15]     P0 = PointF(50, 30)
[16]     P1 = PointF(40, 30)
[17]     P2 = PointF(40, 30)
[18]     P3 = PointF(40, 40)
[19]     Paint.Brush = Paint.Color(Color.Red)
[20]     Paint.MoveTo(P0.x, P0.y)
[21]     Paint.CurveTo(P1.x, P2.y, P2.x, P2.y, P3.x, P3.y)
[22]     Paint.Stroke()
[23]   ' -----------------------------------------------------
[24]   ' Radiator cap
[25]     vP = New Vector
[26]     vP = [40, 40, 40, 80, 100, 88, 152, 88]
[27]     Paint.Brush = Paint.Color(Color.Green)
[28]     Paint.MoveTo(vP[0], vP[1])    
[29]     Paint.CurveTo(vP[2], vP[3], vP[4], vP[5], vP[6], vP[7])
[30]     Paint.Stroke()
[31]   ' -----------------------------------------------------    
[32]   ' Windscreen and roof
[33]     vP = New Vector
[34]     vP = [152, 88, 160, 152, 232, 128, 308, 104]
[35]     Paint.Brush = Paint.Color(Color.Red)
[36]     Paint.MoveTo(vP[0], vP[1])    
[37]     Paint.CurveTo(vP[2], vP[3], vP[4], vP[5], vP[6], vP[7])
[38]     Paint.Stroke()
[39]   ' -----------------------------------------------------    
[40]   ' Boot cover
[41]     vP = New Vector
[42]     vP = [308, 104, 340, 92, 344, 60, 400, 40]
[43]     Paint.Brush = Paint.Color(Color.Blue)
[44]     Paint.MoveTo(vP[0], vP[1])    
[45]     Paint.CurveTo(vP[2], vP[3], vP[4], vP[5], vP[6], vP[7])
[46]     Paint.Stroke
[47]   ' -----------------------------------------------------    
[48]   ' Rear bumper
[49]     vP = New Vector
[50]     vP = [400, 40, 420, 30, 420, 30, 400, 30]
[51]     Paint.Brush = Paint.Color(Color.Red)
[52]     Paint.MoveTo(vP[0], vP[1])    
[53]     Paint.CurveTo(vP[2], vP[3], vP[4], vP[5], vP[6], vP[7])
[54]     Paint.Stroke()
[55]   ' -----------------------------------------------------    
[56]   ' Bottom plate
[57]     Paint.AntiAlias = False      
[58]       Paint.LineWidth = 1
[59]       Paint.Brush = Paint.Color(Color.Black)
[60]       Paint.MoveTo(400, 30)
[61]       Paint.LineTo(50, 30)
[62]       Paint.Stroke
[63]     Paint.AntiAlias = True
[64]   ' Front wheel
[65]     Paint.Brush = Paint.Color(Color.DarkGreen)    
[66]     Paint.Arc(100, 30, 30)
[67]     Paint.Fill
[68]     Paint.Brush = Paint.Color(Color.Gray)
[69]     Paint.Arc(100, 30, 17)
[70]     Paint.Fill()
[71]   ' Rear wheel
[72]     Paint.Brush = Paint.Color(Color.DarkGreen)
[73]     Paint.Arc(300, 30, 30)
[74]     Paint.Fill()
[75]     Paint.Brush = Paint.Color(Color.Gray)
[76]     Paint.Arc(300, 30, 17)    
[77]     Paint.Fill()
[78]   ' TEXT AND SYMBOL
[79]     Paint.NewPath
[80]     Paint.Scale(1 / 1.3, -1 / 1.3) ' Zoom = 1 and y-axis now with *positive* values downwards!
[81]     Paint.AntiAlias = False
[82]       Paint.Brush = Paint.Color(Color.Gray)
[83]       Paint.MoveTo(10, -220)
[84]       Paint.LineTo(540, -220)
[85]       Paint.Stroke()
[86]     Paint.AntiAlias = True
[87]     Paint.Font = Font["Monospace, 30"]
[88]     Paint.DrawText("LEHMANN-DESIGN", 80, -230) ' Text
[89]     Paint.Font = Font["Monospace, 30, bold"]
[90]     Paint.Brush = Paint.Color(Color.Red)
[91]     Paint.DrawText(String.Chr(9812), 430, -250) ' Crown symbol
[92]   Paint.End()
[93]   
[94] End

Comment:

Download

Chapter & Projects

Download