Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
SVG drawing example : Polygons!
#1
Another demo program showing how to draw SVGs and load them via memory buffer to use SVG as an alternative drawing method.
SVG's can draw polygons with a simple path definition that is mostly string of numbers.
this string "<path  stroke ='#FFFFFF' fill='#FF0000'  stroke-width='3' d ='M 200 200 700 200 700 400 200 400 200 200'/>" would draw a red rectangle with a 3 pixel wide white border if embedded in complete SVG string. The polygon is simply defined as a series of points. The only variation in this series of points is the use of M which tells any program drawing the path to move to the following point instead of drawing to the point.

In this example the subroutione svgpoly$  will take a randomly defined polygons and convert them into an SVGpath description held in a string. The path descriptions will be inserted into a complete SVG definition and loaded into a memory buffer and displayed.

Code: (Select All)
'SVG polygon drawing example
'drawing polygons with paths
'a QB64 example by James D. Jarvis
'works with QB64-PE version 3.9.0 and later

'
'this demonstrates how to use subroutines to build a multiple polygon definitions and combine them into a memory buffer that is
'loaded and displayed

Screen _NewImage(800, 500, 32)
Randomize Timer
Dim si As _Unsigned Long 'the SVG image buffer, it's an image handle like any other
Do
    Cls , _RGB32(Int(Rnd * 256), Int(Rnd * 256), Int(Rnd * 256)) 'clear the screen and fill it with a random color
    ss$ = "" 'the the SVG string
    'build the polygons for the demo
    np = Int(6 + Int(Rnd * 100))
    If Rnd * 100 < 3 Then np = np * 20
    For p = 1 To np
        ss$ = ss$ + svgpoly$(Int(25 + Rnd * (_Width - 50)), Int(25 + Rnd * (_Height - 50)), Int(10 + Rnd * 100), Int(10 + Rnd * 120), (Int(Rnd * 90)), Int(1 + Rnd * 10), _RGB32(Int(Rnd * 256), Int(Rnd * 256), Int(Rnd * 256)), _RGB32(Int(Rnd * 256), Int(Rnd * 256), Int(Rnd * 256)))
    Next p
    'take the polygon defintions and compine them with the rest of the SVG string
    ss$ = "<svg width='" + _Trim$(Str$(_Width)) + "' height='" + _Trim$(Str$(_Height)) + "'>" + ss$ + " </svg>" 'putting all those polygons inside an SVG as large as the window
    si = _LoadImage(ss$, 32, "memory") 'load the svg described in ss$ into memory
    _PutImage (0, 0), si 'put the svg on the screen, using 0,0 because the source SVG is as large as the window
    tt$ = Str$(p) + " polygons": _Title tt$ 'put the polygon count in the window title
    Sleep
    _FreeImage si 'free the image so we can load a new one without wasting memory or if we are exiting the program

Loop Until InKey$ = Chr$(27)
'_CLIPBOARD$ = ss$      'windows users can uncomment the commad on the left to dump the last sbg drawn to their clipboard.

Function svgpoly$ (cx, cy, rr, shapedeg, turn, ww, bklr As _Unsigned Long, fklr As _Unsigned Long)
    'filled rotated polygon returned as a string portion of an svg string buffer
    'cx,cy are center of polygon
    'rr oios radius of polygon
    'shapedeg is the angle forming the basis of the polygon , if it doesn't divide into 360 evenly an irregular polygon will be created
    'turn will be the angle the whole polygon is turned off of 0 degree
    'ww is the width fo the border border stroke of the polygon
    'output returned from theis function will be astring holding an SVG path describing a polygon.
    '
    'define the path that will form the polygon and fill the border and fill colors
    i$ = i$ + "<path  stroke ='" + packcolorN$(bklr) + "' fill='" + packcolorN$(fklr) + "' "
    'add the stroke width
    i$ = i$ + " stroke-width='" + _Trim$(Str$(ww)) + "' "

    'find the 1st point in the polygon
    x = rr * Sin(0.01745329 * turn)
    y = rr * Cos(0.01745329 * turn)
    'tell the svg to draw the path by moving to the first point of the polygon
    i$ = i$ + "d ='M"
    i$ = i$ + Str$(cx + x) + Str$(cy + y) + Str$(cx + x) + Str$(cy + y)
    'find the perimter of the polygon
    For deg = turn To turn + 360 Step shapedeg
        x2 = rr * Sin(0.01745329 * deg)
        y2 = rr * Cos(0.01745329 * deg)
        'record the consecutive points of the polygon  that will be drawn to form the path that defines the polygon perimeter
        i$ = i$ + Str$(cx + x2) + Str$(cy + y2)
    Next
    'close the polyon by drawing to the first point
    i$ = i$ + Str$(cx + x) + Str$(cy + y)
    i$ = i$ + "'/>" 'end the path definition of the polygon
    svgpoly$ = i$ 'return this path holding a polygon definiton to the SVG to be drawn
End Function
Function packcolorN$ (klr As _Unsigned Long)
    'convert an unsigned long color value into a hexidecimal # that will be used in an SVG
    Dim As _Unsigned Long rk, gk, bk
    'get the color channels of the unsinged long color
    rk = _Red32(klr)
    gk = _Green32(klr)
    bk = _Blue32(klr)
    'convert those channel values into hexidecimal
    If rk < 16 Then
        r$ = "0" + Hex$(rk) 'put in a padded hexidcimal value
    Else
        r$ = Hex$(rk) 'put in a 2 digit hexidecimal value
    End If
    If gk < 16 Then
        g$ = "0" + Hex$(gk) 'put in a padded hexidcimal value
    Else
        g$ = Hex$(gk) 'put in a 2 digit hexidecimal value
    End If
    If bk < 16 Then
        b$ = "0" + Hex$(bk) 'put in a padded hexidcimal value
    Else
        b$ = Hex$(bk) 'put in a 2 digit hexidecimal value
    End If
    packcolorN$ = "#" + r$ + g$ + b$
End Function
Reply




Users browsing this thread: 1 Guest(s)