Path Module (RoundBox, Hexagon, WaveLine, LoopLine)
Posted: Sat Sep 05, 2015 4:36 pm
- PB 5.40
- shape: hexagon, roundbox
- option: 4 Corners Radius
- waves line
- loops line
- shape: hexagon, roundbox
- option: 4 Corners Radius
- waves line
- loops line

Code: Select all
DeclareModule PathAddons
Enumeration
#PB_WavePath_Default=0
#PB_WavePath_Triangle
#PB_WavePath_Square
#PB_WavePath_Sine
#PB_WavePath_Sawtooth
#PB_LoopPath_Default=0
#PB_LoopPath_Open
EndEnumeration
Declare PathWaveType(WaveType=#PB_WavePath_Default)
Declare PathLoopType(LoopType=#PB_LoopPath_Default)
Declare PathCornerRadius(x0.d, y0.d=#PB_Ignore, x1.d=#PB_Ignore, y1.d=#PB_Ignore, x2.d=#PB_Ignore, y2.d=#PB_Ignore, x3.d=#PB_Ignore, y3.d=#PB_Ignore)
Declare AddPathRoundBox(x.d, y.d, Width.d, Height.d, Flags=#PB_Path_Default)
Declare AddPathHexagon(x.d, y.d, Width.d, Height.d, Flags=#PB_Path_Default)
Declare AddPathWaveLine(x.d, y.d, Count, Amplitude.d, Flags=#PB_Path_Default)
Declare AddPathLoopLine(x.d, y.d, Count, Amplitude1.d, Amplitude2.d, Scale.d, Flags=#PB_Path_Default)
EndDeclareModule
Module PathAddons
EnableExplicit
Structure CORNER_RADIUS
x.d
y.d
EndStructure
Global CurrentWaveType=#PB_WavePath_Default
Global CurrentLoopType=#PB_LoopPath_Default
Global Dim CornerRadius.CORNER_RADIUS(3)
Procedure PathWaveType(WaveType=#PB_WavePath_Default)
CurrentWaveType=WaveType
EndProcedure
Procedure PathLoopType(LoopType=#PB_LoopPath_Default)
CurrentLoopType=LoopType
EndProcedure
Procedure PathCornerRadius(x0.d, y0.d=#PB_Ignore, x1.d=#PB_Ignore, y1.d=#PB_Ignore, x2.d=#PB_Ignore, y2.d=#PB_Ignore, x3.d=#PB_Ignore, y3.d=#PB_Ignore)
CornerRadius(0)\x=x0
If y0=#PB_Ignore : y0=x0 : EndIf : CornerRadius(0)\y=y0
If x1<>#PB_Ignore And y1<>#PB_Ignore And x2=#PB_Ignore And y2=#PB_Ignore And x3=#PB_Ignore And y3=#PB_Ignore
x2=x1 : y2=y1
x3=x1 : y3=y1
x1=x0 : y1=y0
EndIf
If x1=#PB_Ignore : x1=x0 : EndIf : CornerRadius(1)\x=x1
If y1=#PB_Ignore : y1=y0 : EndIf : CornerRadius(1)\y=y1
If x2=#PB_Ignore : x2=x1 : EndIf : CornerRadius(2)\x=x2
If y2=#PB_Ignore : y2=y1 : EndIf : CornerRadius(2)\y=y2
If x3=#PB_Ignore : x3=x2 : EndIf : CornerRadius(3)\x=x3
If y3=#PB_Ignore : y3=y2 : EndIf : CornerRadius(3)\y=y3
EndProcedure
Procedure AddPathRoundBox(x.d, y.d, Width.d, Height.d, Flags=#PB_Path_Default)
MovePathCursor(x + CornerRadius(0)\x, y, Flags & #PB_Path_Relative)
AddPathEllipse(0, CornerRadius(0)\y, CornerRadius(0)\x, CornerRadius(0)\y, 180, -90, #PB_Path_Relative)
AddPathLine(Width-CornerRadius(0)\x-CornerRadius(1)\x, 0, #PB_Path_Relative)
AddPathEllipse(0, CornerRadius(1)\y, CornerRadius(1)\x, CornerRadius(1)\y, -90, 0, #PB_Path_Connected | #PB_Path_Relative)
AddPathLine(0, Height-CornerRadius(1)\y-CornerRadius(2)\y, #PB_Path_Relative)
AddPathEllipse(-CornerRadius(2)\x, 0, CornerRadius(2)\x, CornerRadius(2)\y, 0, 90, #PB_Path_Connected | #PB_Path_Relative)
AddPathLine(CornerRadius(2)\x + CornerRadius(3)\x-Width, 0, #PB_Path_Relative)
AddPathEllipse(0, -CornerRadius(3)\y, CornerRadius(3)\x, CornerRadius(3)\y, 90, 180, #PB_Path_Connected | #PB_Path_Relative)
ClosePath()
MovePathCursor(0, -CornerRadius(0)\y, #PB_Path_Relative)
EndProcedure
Procedure AddPathHexagon(x.d, y.d, Width.d, Height.d, Flags=#PB_Path_Default)
MovePathCursor(x, y + CornerRadius(0)\y, Flags & #PB_Path_Relative)
AddPathLine(CornerRadius(0)\x, -CornerRadius(0)\y, #PB_Path_Relative)
AddPathLine(Width-CornerRadius(0)\x-CornerRadius(1)\x, 0, #PB_Path_Relative)
AddPathLine(CornerRadius(1)\x, CornerRadius(1)\y, #PB_Path_Relative)
AddPathLine(0, Height-CornerRadius(1)\y-CornerRadius(2)\y, #PB_Path_Relative)
AddPathLine(-CornerRadius(2)\x, CornerRadius(2)\y, #PB_Path_Relative)
AddPathLine(CornerRadius(2)\x + CornerRadius(3)\x-Width, 0, #PB_Path_Relative)
AddPathLine(-CornerRadius(3)\x, -CornerRadius(3)\y, #PB_Path_Relative)
ClosePath()
MovePathCursor(0, -CornerRadius(0)\y, #PB_Path_Relative)
EndProcedure
Procedure AddPathWaveLine(x.d, y.d, Count, Amplitude.d, Flags=#PB_Path_Default)
If Count>0
Protected.d xs=PathCursorX(), ys=PathCursorY() ;start pos
Protected.d xd=x, yd=y ;destination pos
Protected.d dx=(xd-xs), dy=(yd-ys) ;distances
If (Flags & #PB_Path_Relative) : dx=x : dy=y : EndIf
Protected.d distHalf=Sqr(dx*dx + dy*dy) / Count / 2, distQuarter=distHalf / 2
Protected.i i
SaveVectorState()
RotateCoordinates(xs, ys, Degree(ATan2(dx, dy)))
Select CurrentWaveType
Case #PB_WavePath_Default
For i=1 To Count
AddPathCurve(distQuarter, -Amplitude, distQuarter, -Amplitude, distHalf, 0, #PB_Path_Relative)
AddPathCurve(distQuarter, Amplitude, distQuarter, Amplitude, distHalf, 0, #PB_Path_Relative)
Next
Case #PB_WavePath_Triangle
For i=1 To Count
AddPathLine(distQuarter, -Amplitude, #PB_Path_Relative)
AddPathLine(distHalf, 2*Amplitude, #PB_Path_Relative)
AddPathLine(distQuarter, -Amplitude, #PB_Path_Relative)
Next
Case #PB_WavePath_Square
For i=1 To Count
AddPathLine(0, -Amplitude, #PB_Path_Relative)
AddPathLine(distHalf, 0, #PB_Path_Relative)
AddPathLine(0, 2*Amplitude, #PB_Path_Relative)
AddPathLine(distHalf, 0, #PB_Path_Relative)
AddPathLine(0, -Amplitude, #PB_Path_Relative)
Next
Case #PB_WavePath_Sawtooth
For i=1 To Count
AddPathLine(distHalf, -Amplitude, #PB_Path_Relative)
AddPathLine(0, 2*Amplitude, #PB_Path_Relative)
AddPathLine(distHalf, -Amplitude, #PB_Path_Relative)
Next
Case #PB_WavePath_Sine
For i=1 To Count
AddPathCurve(distQuarter / 2, -Amplitude / 2, 1.5*distQuarter, -Amplitude / 2, distHalf, 0, #PB_Path_Relative)
AddPathCurve(distQuarter / 2, Amplitude / 2, 1.5*distQuarter, Amplitude / 2, distHalf, 0, #PB_Path_Relative)
;AddPathEllipse(distQuarter, 0, distQuarter, Amplitude, 180, 360, #PB_Path_Relative)
;AddPathEllipse(distQuarter, 0, distQuarter, Amplitude, 180, 0, #PB_Path_Relative | #PB_Path_CounterClockwise)
Next
EndSelect
RestoreVectorState()
EndIf
EndProcedure
Procedure AddPathLoopLine(x.d, y.d, Count, Amplitude1.d, Amplitude2.d, Scale.d, Flags=#PB_Path_Default)
If Count>0
Protected.d xs=PathCursorX(), ys=PathCursorY() ;start pos
Protected.d xd=x, yd=y ;destination pos
Protected.d dx=(xd-xs), dy=(yd-ys) ;distances
If (Flags & #PB_Path_Relative) : dx=x : dy=y : EndIf
Protected.d distHalf=Sqr(dx*dx + dy*dy) / 2, dist1, dist2, k=1 / Scale
Protected.i i
SaveVectorState()
RotateCoordinates(xs, ys, Degree(ATan2(dx, dy)))
Select CurrentLoopType
Case #PB_LoopPath_Default
dist1=k*distHalf / (Count*(k-1) + k)
dist2=dist1 / k
AddPathEllipse(dist1, 0, dist1, Amplitude1, -180, 0, #PB_Path_Connected | #PB_Path_Relative)
For i=1 To Count
AddPathEllipse(-dist2, 0, dist2, Amplitude2, 0, 180, #PB_Path_Connected | #PB_Path_Relative)
AddPathEllipse(dist1, 0, dist1, Amplitude1, -180, 0, #PB_Path_Connected | #PB_Path_Relative)
Next
Case #PB_LoopPath_Open
Count + 1
dist1=k*distHalf / (Count*(k-1))
dist2=dist1 / k
For i=1 To Count
AddPathEllipse(dist1, 0, dist1, Amplitude1, -180, 0, #PB_Path_Connected | #PB_Path_Relative)
AddPathEllipse(-dist2, 0, dist2, Amplitude2, 0, 180, #PB_Path_Connected | #PB_Path_Relative)
Next
EndSelect
RestoreVectorState()
EndIf
EndProcedure
EndModule
; ********************
; EXAMPLE
; ********************
UseModule PathAddons
Procedure DrawCurves()
Protected startOffset.d=10.0*ElapsedMilliseconds() / 1000
If StartVectorDrawing(CanvasVectorOutput(0))
; --------------------------------------------
; enable 2X zoom
ScaleCoordinates(2, 2)
; --------------------------------------------
; draw white background
VectorSourceColor(RGBA(255, 255, 255, 255))
FillVectorOutput()
; --------------------------------------------
; draw loop lines
Define.d x=100, y=130
Define amplitude.d=10, count.i=3
MovePathCursor(x, y)
PathLoopType(#PB_LoopPath_Default)
AddPathLoopLine(70, 60, count, amplitude / 2, amplitude / 3, 0.2, #PB_Path_Relative)
VectorSourceColor(RGBA(255, 90, 90, 255))
StrokePath(2, #PB_Path_RoundEnd)
MovePathCursor(x, y)
PathLoopType(#PB_LoopPath_Default)
AddPathLoopLine(70, 60, count, amplitude, amplitude, 0.4, #PB_Path_Relative)
VectorSourceColor(RGBA(38, 255, 0, 140))
StrokePath(3, #PB_Path_RoundEnd)
MovePathCursor(x + 20, y)
PathLoopType(#PB_LoopPath_Open)
AddPathLoopLine(70, 60, count, amplitude / 2, amplitude / 3, 0.2, #PB_Path_Relative)
VectorSourceColor(RGBA(0, 251, 255, 200))
StrokePath(3, #PB_Path_RoundEnd)
; --------------------------------------------
; draw dash line
Define.d x=10, y=90
MovePathCursor(x, y)
AddPathLine(90, 90, #PB_Path_Relative)
VectorSourceColor(RGBA(255, 0, 50, 255))
DashPath(2, 5)
; --------------------------------------------
; draw wave lines
Define amplitude.d=20, count.i=2
MovePathCursor(x, y)
PathWaveType(#PB_WavePath_Default)
AddPathWaveLine(90, 90, count, amplitude, #PB_Path_Relative)
VectorSourceColor(RGBA(255, 90, 90, 255))
StrokePath(3, #PB_Path_RoundEnd)
MovePathCursor(x, y)
PathWaveType(#PB_WavePath_Sawtooth)
AddPathWaveLine(90, 90, count, amplitude, #PB_Path_Relative)
VectorSourceColor(RGBA(0, 251, 255, 200))
StrokePath(3, #PB_Path_RoundEnd)
MovePathCursor(x, y)
PathWaveType(#PB_WavePath_Sine)
AddPathWaveLine(90, 90, count, amplitude, #PB_Path_Relative)
VectorSourceColor(RGBA(185, 0, 255, 100))
StrokePath(3, #PB_Path_RoundEnd)
MovePathCursor(x, y)
PathWaveType(#PB_WavePath_Square)
AddPathWaveLine(90, 90, count, amplitude, #PB_Path_Relative)
VectorSourceColor(RGBA(38, 255, 0, 140))
StrokePath(3, #PB_Path_RoundEnd)
MovePathCursor(x, y)
PathWaveType(#PB_WavePath_Triangle)
AddPathWaveLine(90, 90, count, amplitude, #PB_Path_Relative)
VectorSourceColor(RGBA(60, 100, 200, 200))
DotPath(3, 5, #PB_Path_RoundEnd, startOffset)
; --------------------------------------------
; draw round boxs
PathCornerRadius(10)
AddPathRoundBox(10, 10, 50, 50)
PathCornerRadius(10, 20)
AddPathRoundBox(60, 0, 50, 50, #PB_Path_Relative)
PathCornerRadius(25, 20, 20, 10)
AddPathRoundBox(60, 0, 50, 50, #PB_Path_Relative)
PathCornerRadius(10, 20, 20, 10, 20, 10)
AddPathRoundBox(0, 60, 50, 50, #PB_Path_Relative)
PathCornerRadius(25, 40, 10, 10, 25, 40, 10, 10)
AddPathRoundBox(-60, 0, 50, 50, #PB_Path_Relative)
VectorSourceColor(RGBA(255, 90, 90, 255))
StrokePath(3, #PB_Path_RoundEnd)
; --------------------------------------------
; draw hexagons on Layer
BeginVectorLayer(200)
PathCornerRadius(10)
AddPathHexagon(10, 10, 50, 50)
PathCornerRadius(10, 20)
AddPathHexagon(60, 0, 50, 50, #PB_Path_Relative)
PathCornerRadius(25, 20, 20, 10)
AddPathHexagon(60, 0, 50, 50, #PB_Path_Relative)
PathCornerRadius(10, 20, 20, 10, 20, 10)
AddPathHexagon(0, 60, 50, 50, #PB_Path_Relative)
PathCornerRadius(25, 40, 10, 10, 25, 40, 10, 10)
AddPathHexagon(-60, 0, 50, 50, #PB_Path_Relative)
VectorSourceColor(RGBA(60, 100, 200, 255))
DotPath(3, 5, #PB_Path_RoundEnd, startOffset)
EndVectorLayer()
StopVectorDrawing()
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 400, 400, "Animated Vector Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 400, 400)
AddWindowTimer(0, 100, 1000 / 30)
BindEvent(#PB_Event_Timer, @DrawCurves())
Repeat
Event=WaitWindowEvent()
Until Event=#PB_Event_CloseWindow
EndIf