Page 1 of 2

Path Module (RoundBox, Hexagon, WaveLine, LoopLine)

Posted: Sat Sep 05, 2015 4:36 pm
by eddy
- PB 5.40
- shape: hexagon, roundbox
- option: 4 Corners Radius
- waves line
- loops line

Image

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

Re: Path Module (RoundBox, Hexagon)

Posted: Sat Sep 05, 2015 6:01 pm
by said
Nice! Thanks for sharing, the new Vector library seems very interesting :D i hope i can find some time soon to test it out.

Re: Path Module (RoundBox, Hexagon)

Posted: Sat Sep 05, 2015 10:51 pm
by davido
@eddy,
Very nice, thank you for sharing. :D
Looks great on Windows 7

Incidentally, I assume you wrote it for Windows OS.
But I cannot see why it shouldn't look the same on Mac OS X, however, it looks very different.

Re: Path Module (RoundBox, Hexagon)

Posted: Sat Sep 05, 2015 11:09 pm
by eddy
davido wrote:@eddy,
Very nice, thank you for sharing. :D
Looks great on Windows 7

Incidentally, I assume you wrote it for Windows OS.
But I cannot see why it shouldn't look the same on Mac OS X, however, it looks very different.
What kind of differences ? (shape or color)

Re: Path Module (RoundBox, Hexagon)

Posted: Sun Sep 06, 2015 4:14 am
by eddy
Updated
- PathWaveType : default, sine, square, triangle, sawtooth
- AddPathWaveLine

Re: Path Module (RoundBox, Hexagon)

Posted: Sun Sep 06, 2015 5:32 am
by wilbert
davido wrote:Incidentally, I assume you wrote it for Windows OS.
But I cannot see why it shouldn't look the same on Mac OS X, however, it looks very different.
It shouldn't be this different.
Fred should take a look at this because this definitely is a bug !

Re: Path Module (RoundBox, Hexagon)

Posted: Sun Sep 06, 2015 8:09 am
by davido
@wilbert,
Thank you for your comments, I'll just check with eddy, first.
@eddy,
This is what it looks like on the Mac.
If you think it is a bug, I will so post it. However, I don't wish to overburden Fred with none-bugs.
Image

Is there some way to specify the picture size in the url tags?

Re: Path Module (RoundBox, Hexagon)

Posted: Sun Sep 06, 2015 8:56 am
by Vera
davido wrote:Is there some way to specify the picture size in the url tags?
No.
Unfortunately tinypic doesn't provide different sizes after you've uploaded a picture. You would have to preset/choose the size before submitting.
But I figured out a trick: you could use the thumbnail preview of your picture and embrace it within URL-tags leading to the original image. (seems only '_th' has to be added to the image-name to get hold of it)

edit: [removed imaged-image-link to slim posting]
This is how it will appear with the BB-code like this: (ready for you to copy if you'd like to use it in your posting)

Code: Select all

[url=http://i62.tinypic.com/jqrn68.png][img]http://i62.tinypic.com/jqrn68_th.png[/img][/url]
edit: @davido ~ You're welcome ~ it was my pleasure Image

Re: Path Module (RoundBox, Hexagon)

Posted: Sun Sep 06, 2015 11:48 am
by davido
@Vera,

Now that was clever.
Thank you, very much.
I've corrected my post. :D

@eddy,
Thank you for posting the bug report.

Re: Path Module (RoundBox, Hexagon, WaveLine)

Posted: Sun Sep 06, 2015 3:26 pm
by eddy
Updated
- PathLoopType : default, open
- AddLoopWaveLine

Re: Path Module (RoundBox, Hexagon, WaveLine, LoopLine)

Posted: Sun Sep 06, 2015 8:35 pm
by Erlend
A quick test shows a difference between windows and linux. Seems the DotPath() command is a bit "off", if I change the code to say "DotPath(3,4)" instead of "DotPath(3,1)" as in eddy 's code. The result is the same, so the distance parameter of DotPath is handled different on the two OS's, could someone confirm this so we can add that to bug lit??
Image

Re: Path Module (RoundBox, Hexagon, WaveLine, LoopLine)

Posted: Sat Sep 12, 2015 7:17 pm
by collectordave
Hi eddy

Great. Do you mind if I try to incorporate these into my Print and Preview Module?

Cheers

Re: Path Module (RoundBox, Hexagon, WaveLine, LoopLine)

Posted: Sun Sep 13, 2015 10:35 pm
by eddy
collectordave wrote:Hi eddy

Great. Do you mind if I try to incorporate these into my Print and Preview Module?

Cheers
Feel free to use it

Re: Path Module (RoundBox, Hexagon, WaveLine, LoopLine)

Posted: Mon Sep 14, 2015 7:04 am
by collectordave
Thanks eddy,

Pushed me in the right direction.

Now have a routine for displaying and printing all regular polygons from triangle to decagon and working on other complex shapes.

Re: Path Module (RoundBox, Hexagon, WaveLine, LoopLine)

Posted: Fri Sep 18, 2015 5:46 pm
by freak
Please note the changes here: http://www.purebasic.fr/english/viewtop ... 92#p471992

The DotPath() command above must be adjusted to have a larger 'Distance'. Otherwise it looks like a solid line.