Date: 02-16-2022
Return to Index
created by gbSnippets
'Compilable Example: (Jose Includes)
#Compiler PBWin 10
#Compile Exe
#Dim All
%Unicode = 1
#Include "Win32API.inc"
%IDC_Graphic = 500
%IDC_Button = 501
Global hDlg As Dword, P() As Point, pCount As Long
Function PBMain() As Long
Dialog New Pixels, 0, "Smooth Curve from Series of Points",300,300,400,400, %WS_OverlappedWindow To hDlg
Control Add Button, hDlg, %IDC_Button, "Clear", 5,5,50,20
Control Add Graphic, hDlg, %IDC_Graphic, "", 0, 30, 400,400, %SS_Notify
Graphic Attach hDlg, %IDC_Graphic
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
Local pt As Point
Select Case Cb.Msg
Case %WM_InitDialog
pCount = 0 : ReDim P(0)
Case %WM_Command
Select Case Cb.Ctl
Case %IDC_Button
pCount = 0 : ReDim P(0) : Graphic Clear
Case %IDC_Graphic
GetCursorPos pt
ScreenToClient hDlg, pt
pt.y = pt.y - 30
ReDim Preserve P(pCount)
P(pCount) = pt
If pCount > 2 Then DrawCurves 0.01, 0.5
Graphic Box (P(pCount).x-5,P(pCount).y-5)-(P(pCount).x+5,P(pCount).y+5),,%Red
Incr pCount
End Select
End Select
End Function
Function BX(ByVal t As Single, ByVal x0 As Single, ByVal x1 As Single, ByVal x2 As Single, ByVal x3 As Single) As Single
Function = x0 * (1 - t) ^ 3 + _
x1 * 3 * t * (1 - t) ^ 2 + _
x2 * 3 * t ^ 2 * (1 - t) + _
x3 * t ^ 3
End Function
Function BY(ByVal t As Single, ByVal y0 As Single, ByVal y1 As Single, ByVal y2 As Single, ByVal y3 As Single) As Single
Function = y0 * (1 - t) ^ 3 + _
y1 * 3 * t * (1 - t) ^ 2 + _
y2 * 3 * t ^ 2 * (1 - t) + _
y3 * t ^ 3
End Function
Sub DrawBezier(ByVal dt As Single, pt0 As Point, pt1 As Point, pt2 As Point, pt3 As Point)
Local t,x0,y0,x1,y1 As Single
' Draw the control lines.
Graphic Style 2 'dot
Graphic Line (pt0.X, pt0.Y)-(pt1.X, pt1.Y), %Red
Graphic Line (pt2.X, pt2.Y)-(pt3.X, pt3.Y), %Red
Graphic Style 0 'solid
' Draw the curve.
t = 0
x1 = BX(t, pt0.X, pt1.X, pt2.X, pt3.X)
y1 = BY(t, pt0.Y, pt1.Y, pt2.Y, pt3.Y)
t = t + dt
Do While t < 1
x0 = x1 : y0 = y1
x1 = BX(t, pt0.X, pt1.X, pt2.X, pt3.X)
y1 = BY(t, pt0.Y, pt1.Y, pt2.Y, pt3.Y)
Graphic Line (x0, y0)-(x1, y1), %Blue
t = t + dt
Loop
' Connect to the final point.
t = 1
x0 = x1 : y0 = y1
x1 = BX(t, pt0.X, pt1.X, pt2.X, pt3.X)
y1 = BY(t, pt0.Y, pt1.Y, pt2.Y, pt3.Y)
Graphic Line (x0, y0)-(x1, y1), %Blue
End Sub
Sub DrawCurves(ByVal dt As Single, ByVal tension As Single)
Local control_scale As Single, i As Integer
Local pt,pt_before, pt_after, pt_after2, Di, DiPlus1, p1, p2, p3, p4 As Point
Graphic Clear
control_scale = CSng(tension / 0.5 * 0.175)
For i = 0 To UBound(P) - 1
pt_before = P(Max(i - 1, 0))
pt = P(i)
pt_after = P(i + 1)
pt_after2 = P(Min(i + 2, UBound(P)))
p1 = P(i)
p4 = P(i + 1)
Di.X = pt_after.X - pt_before.X
Di.Y = pt_after.Y - pt_before.Y
p2.X = pt.X + control_scale * Di.X
p2.Y = pt.Y + control_scale * Di.Y
DiPlus1.X = pt_after2.X - P(i).X
DiPlus1.Y = pt_after2.Y - P(i).Y
p3.X = pt_after.X - control_scale * DiPlus1.X
p3.Y = pt_after.Y - control_scale * DiPlus1.Y
DrawBezier dt, p1, p2, p3, p4
Graphic Box (P(i).x-5,P(i).y-5)-(P(i).x+5,P(i).y+5),,%Red
Next i
End Sub
'gbs_01410
'Date: 10-17-2014
http://www.garybeene.com/sw/gbsnippets.htm