Author Topic: Cartesian Active Layout Mapper, a general purpose library  (Read 1201 times)

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
Cartesian Active Layout Mapper, a general purpose library
« on: January 03, 2011, 06:08:05 PM »
comes in 3 files:
calmcompinit.bas
Code: [Select]
' (CALMcompinit), goes with module:  CALMcompfunc
'       Version:  1.07.000

CONST lod_max_siz = 15000                  ' i.e. limit max number of points
CONST scan_max_size_default# = 1600 ^ 2 + 1   ' max size for the image, if larger image is read-> error

DIM SHARED CALM_data(0 TO lod_max_siz, 0 TO 2) AS _UNSIGNED LONG
  'structure of CALM_data:
  '  ,0 : x coordinate    ,1 : y coordinate    ,2 : *unsigned* flag color
DIM SHARED CALM_hschema AS LONG
DIM SHARED CALMexpectsizeh, CALMexpectsizev
DIM SHARED CALMtailtype AS LONG
DIM SHARED DetectCol&
DIM SHARED CALMwhitecalib AS _UNSIGNED LONG
REDIM SHARED CALM_pointsArr(1) AS LONG '  set to shared
'then can be adjusted away from default size
REDIM CALM_pointsArr&(scan_max_size_default#) '                < ----- !

'>>>>>>>> set some defaults <<<<<<
 dglscanMin = 3 ' identifying tail must be at least this long; > 3 is good
 dglscanLen = 20

calmcompfunc.bas
Code: [Select]
' Cartesian Active Layout Mapper                   Version:  1.08.762
'  module:  calmcompfunc
'  requires added file:  calmcompinit (1.07+), polydetect (1.00+)

'summary:
' populates an array with coordinate data matching the layout outlined by an image file
' in the image, a coordinate is set by a bracket with a tail, optionally having at it's end a colored pixel area called a 'flag'
' flags are color coded to specify position within the array at time of reading. red component values are measured first while blues are least significant
' since functions can't return an array, a shared data array is utilized
'

'useful function list:
'         ReadLayout (DestAr() AS LONG, lyfile$, skiporder)
'         ShowBox (pairslayout() AS LONG, idx, label$, maxscale, destHandle&)
'         ShowBunch (lodSubset() AS LONG, label$, maxscale, destHandle& | LayerHue(destHandle&,shapecolor&))
'numpts% = ReadPoints (pairslayout() AS LONG)
'decide% = CheckPair (pairslayout() AS LONG, idx, px, py)
'decide% = CheckBunch (pairslayout() AS LONG, px, py)   ' prototypical procedure for checking a shape
'         pdLineUpPoints (pointdat(), linedat())    ' -- line data generated and passed back
'         GenerateShapeMask (maskhandle&, pointdat(), linedat(), xo, yo)
'decide% = pdPointCheck(x, y, linedat()) ' i.e. check point x, y returning -1 if inside the shape

'example flag:
'
'                        xxxxxxx
'                    @@  x
'                   @@@  x
'                   @@x  x
'                      x x
'                       xx
'                        x
'
' [@ = colored pixel determining read order]

'!! use REDIM CALM_pointsArr& for images larger than the default set in the layouterinit file


FUNCTION apoint& (ax, ay)
apoint& = CLNG(CALM_pointsArr(1 + ax + ay * CALMexpectsizeh))
END FUNCTION

FUNCTION getTailLen% (x1, y1, extsgn)

SHARED dglscanMin, dglscanLen
'note- DetectCol& is assumed to be properly set in the parent sub

ydir = extsgn
IF apoint&(x1 + extsgn, y1 - extsgn) = DetectCol& THEN ydir = -ydir

'todo- if tail is cut off by originating too near the left or right, it should be h-reversed
'   so add condition if near a border look for tail with direcsgn = -direcsgn

tp = 0
FOR i = 1 TO dglscanLen + 1

  x1c = x1 + i * extsgn
  y1c = y1 + i * ydir
  IF apoint&(x1c, y1c) = DetectCol& THEN
    tp = tp + 1
  ELSE
    CALMtailtype = apoint&(x1c, y1c)
    EXIT FOR
  END IF

NEXT i

getTailLen% = tp

'set to 0 if len below minimum
IF tp < dglscanMin THEN
  getTailLen% = 0
  CALMtailtype = 0
END IF

END FUNCTION


SUB InterpLayout (npr)
' npr -- i.e. number of points read [from layout image]
DetectCol& = &HFF000000 ' ideally something in the low rgb range

SHARED dglscanMin, dglscanLen

scanfordc:
  IF L1wp = -3 THEN 'calibrate new DetectCol& since default wasn't encountered
    dcrc~& = &HFFFFFF9
    FOR i = 1 TO (_HEIGHT(CALM_hschema) - 2) * _WIDTH(CALM_hschema)
      IF CALM_pointsArr(i) < dcrc~& THEN dcrc~& = CALM_pointsArr(i)
    NEXT i
    DetectCol& = dcrc~& 'type mismatch won't affect color values
  END IF
  L1wp = 0

  'analyze each point of the image (excluding a margin around the edge)
  FOR i = dglscanMin - 1 TO CALMexpectsizev + 1 - dglscanMin

    FOR i2 = dglscanMin - 1 TO CALMexpectsizeh + 1 - dglscanMin

      IF apoint&(i2, i) = DetectCol& THEN
        extsgn = -1
tryfindflag:
        IF apoint&(i2, i + extsgn) = DetectCol& AND apoint&(i2 + extsgn, i - extsgn) = DetectCol& THEN
          IF apoint&(i2 + 2 * extsgn, i) = DetectCol& THEN ud = 1 ELSE ud = 0
            iadj = i - 2 * ud * extsgn

            tl = getTailLen%(i2, iadj, extsgn) ' will also place flag color into tailtype

            IF tl > 0 THEN
             CALM_data(L1wp, 2) = CALMtailtype
             CALM_data(L1wp, 0) = i2
             FOR i3 = iadj TO (CALMexpectsizev - 1) * (1 + SGN(extsgn)) / 2 STEP extsgn
               IF i3 = 0 OR i3 = CALMexpectsizev - 1 OR apoint&(i2, i3 + extsgn) <> DetectCol& THEN
                 CALM_data(L1wp, 1) = i3
                 L1wp = L1wp + 1
                 EXIT FOR
               END IF
             NEXT i3
            END IF
        END IF
        IF extsgn = -1 THEN extsgn = 1: GOTO tryfindflag
      END IF
       IF L1wp > UBOUND(CALM_data, 1) THEN EXIT FOR
    NEXT i2
       IF L1wp > UBOUND(CALM_data, 1) THEN EXIT FOR
  NEXT i

  IF L1wp = -3 THEN nodcpresent = -1
  IF L1wp = 0 THEN L1wp = -3 ' signal that standard detect color wasn't encountered
IF L1wp < 1 AND nodcpresent = 0 THEN GOTO scanfordc 'repeat once if needed

'adjust for changing bracket length
SortLoutDataArr 0, L1wp - 1
npr = L1wp 'set to contain the number of points read (if final # is -3, then image may be wrong)

END SUB


SUB ReadLayout (DestAr() AS LONG, lyfile$, skiporder)
' Executes main collection of layouter functions and then unloads image
' ** ERASE CALM_data() at end
'   add future args: param AS groupLOparam

SHARED dglscanMin, dglscanLen

CALM_hschema = _LOADIMAGE(lyfile$, 32)
CALMexpectsizeh = _WIDTH(CALM_hschema): CALMexpectsizev = _HEIGHT(CALM_hschema)
CALMwhitecalib = 0

keepingSH& = _SOURCE
_SOURCE CALM_hschema
GET (0, 0)-STEP(CALMexpectsizeh - 1, CALMexpectsizev - 1), CALM_pointsArr()
_SOURCE keepingSH&

InterpLayout chkL1wp

'usual tasks should make use of flag colors; progression is brightest to dimmest
IF skiporder <> 1 AND skiporder <> -1 THEN
  ReorderLoutDataArr (chkL1wp)
END IF

adjLMS = lod_max_siz: IF UBOUND(DestAr, 1) < adjLMS THEN adjLMS = UBOUND(DestAr, 1)

FOR i = 0 TO adjLMS
  DestAr(i, 0) = CALM_data(i, 0): DestAr(i, 1) = CALM_data(i, 1)
  DestAr(i, 2) = CALM_data(i, 2)
NEXT i
_FREEIMAGE CALM_hschema
ERASE CALM_data

END SUB


SUB ReorderLoutDataArr (Lwpmax)

SHARED dglscanMin, dglscanLen
' note- should be called before the handle CALM_hschema is reset... from within InterpLayout is best
' sorts color flagged points together, and in descending order (red, green, blue, brightest to dimmest) using a buffer

DIM lay0dataBuf(0 TO Lwpmax, 0 TO 3) AS LONG
L1bufwp = 0

'  CALMwhitecalib (this would typically be very close to &HFFFFFFFF )
IF CALMwhitecalib = 0 THEN
  FOR i = 1 TO (_HEIGHT(CALM_hschema) - 2) * _WIDTH(CALM_hschema)
    IF CALM_pointsArr(i) > CALMwhitecalib THEN CALMwhitecalib = CALM_pointsArr(i)
  NEXT i
END IF

lc~& = CALMwhitecalib
rorPrev~& = CALMwhitecalib
rorSmallestC~& = 0
rprgrs = 0

FOR reorder = 0 TO Lwpmax - 1

  IF rprgrs = 3 THEN
    ttyp~& = CALMwhitecalib
  ELSEIF rprgrs = 1 THEN

    ttyp~& = 0

    yy = 0
    FOR ror = 0 TO Lwpmax - 1

      IF CALM_data(ror, 2) < rorPrev~& AND CALM_data(ror, 2) > ttyp~& THEN ttyp~& = CALM_data(ror, 2)
      '''if CALM_data(ror, 2) < lc~& then lc~& = CALM_data(ror, 2)  'need the redundancy?
    NEXT ror

  ELSE 'rprgrs == 0
    ttyp~& = 0

    FOR ror = 0 TO Lwpmax - 1
      IF CALM_data(ror, 2) < rorPrev~& AND CALM_data(ror, 2) > ttyp~& THEN ttyp~& = CALM_data(ror, 2)
      IF CALM_data(ror, 2) < lc~& THEN lc~& = CALM_data(ror, 2)
    NEXT ror

    rorSmallestC~& = lc~&: rprgrs = 1
    IF ttyp~& = 0 THEN rprgrs = 3: ttyp~& = CALMwhitecalib ' this means only found flags w/o color
    '    print "final ";hex$(rorSmallestC~&)    :sleep

  END IF

  FOR ror = 0 TO (Lwpmax - 1) STEP 1
    IF ttyp~& = CALM_data(ror, 2) THEN
      lay0dataBuf(L1bufwp, 0) = CALM_data(ror, 0)
      lay0dataBuf(L1bufwp, 1) = CALM_data(ror, 1)
      lay0dataBuf(L1bufwp, 2) = CALM_data(ror, 2)
      L1bufwp = L1bufwp + 1
    END IF
  NEXT ror

  rorPrev~& = ttyp~&
  '  bad: if ttyp~& = rorSmallestC~& then exit for
  IF rprgrs = 3 THEN EXIT FOR
  IF ttyp~& = rorSmallestC~& THEN rprgrs = 3 ' signal one last looping

  'print "check values ";"- cur ttyp = "; hex$(ttyp~&);"  rorprev = ";hex$(rorPrev~&) : sleep

NEXT reorder

FOR reorderx = 0 TO Lwpmax - 1
  CALM_data(reorderx, 0) = lay0dataBuf(reorderx, 0): CALM_data(reorderx, 1) = lay0dataBuf(reorderx, 1)
  CALM_data(reorderx, 2) = lay0dataBuf(reorderx, 2)
NEXT reorderx

END SUB


SUB SortLoutDataArr (firstp, lastp)
' reorders data elements by bracket corner position (rather than flag position)

ypl# = 250 ^ 2

DO: noneswapped = 1
  FOR i = firstp TO lastp - 1
    FOR k = i + 1 TO lastp
      IF CALM_data(i, 2) = CALM_data(k, 2) THEN EXIT FOR
    NEXT k
    IF CALM_data(i, 2) = CALM_data(k, 2) AND k <> lastp + 1 AND CALM_data(i, 1) * ypl# + CALM_data(i, 0) > CALM_data(k, 1) * ypl# + CALM_data(k, 0) THEN
      SWAP CALM_data(i, 0), CALM_data(k, 0): SWAP CALM_data(i, 1), CALM_data(k, 1)
      SWAP CALM_data(i, 2), CALM_data(k, 2): noneswapped = 0
    END IF

  NEXT i
LOOP UNTIL noneswapped = 1

END SUB


SUB ShowBox (pairslayout() AS LONG, idx, label$, maxscale, destHandle&)

' draws a square and prints a label at the space between an adjacent pair of points
'*( an idx of 1 corresponds to first pair of points

keepingd& = _DEST
_DEST destHandle&

IF _PIXELSIZE > 1 THEN sbboxcolor& = _RGBA(112, 112, 112, 150) ELSE sbboxcolor& = _RGB(112, 112, 112)
IF maxscale <= 0 THEN maxscale = 5 ' sets a default highest label scale

idx2 = (idx - 1) * 2
IF idx2 + 1 > UBOUND(pairslayout, 1) OR idx2 < LBOUND(pairslayout, 1) THEN EXIT SUB

LINE (pairslayout(idx2, 0), pairslayout(idx2, 1))-(pairslayout(idx2 + 1, 0), pairslayout(idx2 + 1, 1)), sbboxcolor&, BF


IF label$ = "" THEN EXIT SUB ' else--
IF _PIXELSIZE > 1 THEN tmph& = _NEWIMAGE(_PRINTWIDTH(label$) + _FONTWIDTH + 1, _FONTHEIGHT, 32) ELSE tmph& = _NEWIMAGE(_PRINTWIDTH(label$) + _FONTWIDTH + 1, _FONTHEIGHT, 256)
IF tmph& < -1 THEN
  keepingd.sub1& = _DEST
  keepfont& = _FONT
  _DEST tmph&
  _FONT keepfont&
  _PRINTMODE _KEEPBACKGROUND
  PRINT label$;
  _DEST keepingd.sub1&
  rescaleX = pairslayout(idx2 + 1, 0): IF rescaleX - pairslayout(idx2, 0) > _PRINTWIDTH(label$) * maxscale THEN rescaleX = pairslayout(idx2, 0) + _PRINTWIDTH(label$) * maxscale - 1
  rescaleY = pairslayout(idx2 + 1, 1): IF rescaleY - pairslayout(idx2, 1) > _FONTHEIGHT * maxscale THEN rescaleY = pairslayout(idx2, 1) + _FONTHEIGHT * maxscale - 1
  _PUTIMAGE (pairslayout(idx2, 0), pairslayout(idx2, 1))-(rescaleX, rescaleY), tmph&, , (0, 0)-(_WIDTH(tmph&) - 1, _HEIGHT(tmph&) - 1)
  _FREEIMAGE tmph&
END IF
''fixed to use default font
'IF label$ = "" THEN EXIT SUB ' else--
'newfont% = 16 ' default handle = 16
'IF _PIXELSIZE > 1 THEN tmph& = _NEWIMAGE(_PRINTWIDTH(label$, newfont%) + _FONTWIDTH(newfont%), _FONTHEIGHT(newfont%), 32) ELSE tmph& = _NEWIMAGE(_PRINTWIDTH(label$, newfont%) + _FONTWIDTH(newfont%), _FONTHEIGHT(newfont%), 256)
'IF tmph& < -1 THEN
'  keepingd& = _DEST
'  _DEST tmph&
'  _PRINTMODE _KEEPBACKGROUND
'  PRINT label$;
'  _DEST keepingd&
'  rescaleX = pairslayout(idx2 + 1, 0): IF rescaleX - pairslayout(idx2, 0) > _PRINTWIDTH(label$, newfont%) * maxscale THEN rescaleX = pairslayout(idx2, 0) + _PRINTWIDTH(label$, newfont%) * maxscale - 1
'  rescaleY = pairslayout(idx2 + 1, 1): IF rescaleY - pairslayout(idx2, 1) > _FONTHEIGHT(newfont%) * maxscale THEN rescaleY = pairslayout(idx2, 1) + _FONTHEIGHT(newfont%) * maxscale - 1
'  _PUTIMAGE (pairslayout(idx2, 0), pairslayout(idx2, 1))-(rescaleX, rescaleY), tmph&, , (0, 0)-(_WIDTH(tmph&) - 1, _HEIGHT(tmph&) - 1)
'  _FREEIMAGE tmph&
'END IF

_DEST keepingd&

END SUB


SUB ShowBunch (lodSubset() AS LONG, label$, maxscale, multipass AS _FLOAT)
' previous version's name changed to ShowBox

np = UBOUND(lodSubset, 1)

IF __Get2(multipass, destHandle&, custcolor&) = 0 THEN
 custcolor& = _RGB32(50, 50, 175) ' set to a default drawing color
END IF

DIM CALM_linedat(0 TO np + 1, 0 TO 3) AS SINGLE
keepingd& = _DEST
_DEST destHandle&

  pdLineUpPoints lodSubset(), CALM_linedat()

FOR i = 0 TO np
  is = i + 1: IF is > np THEN is = 0
  LINE (lodSubset(i, 0), lodSubset(i, 1))-(lodSubset(is, 0), lodSubset(is, 1)), custcolor& OR &HFF000000 ''_RGB32(85, 85, 85)
NEXT i

'paint the inside of our shape...
     '* this method may leave stranded pixels unpainted if some lines are close together
FOR i = 0 TO np
   is = i + 1: IF is > np THEN is = 0
 px = CALM_linedat(np + 1, 1) + (lodSubset(i, 0) + lodSubset(is, 0)) / 2 + 1
 py = CALM_linedat(np + 1, 2) + (lodSubset(i, 1) + lodSubset(is, 1)) / 2 + 1
 IF CALM_linedat(i, 2) = 1 THEN
   IF CALM_linedat(i, 0) > 0 THEN 'further adjust px but not py
    px = px - 2
   END IF
 ELSE 'further adjust py and maybe px
   py = py - 2
   IF CALM_linedat(i, 0) < 0 THEN 'further adjust px
    px = px - 2
   END IF
 END IF

 PAINT (px, py), custcolor&, custcolor& OR &HFF000000

NEXT i

' make 1 of possible print label implementations:
'  place label text horizontally at midpoint of first line, running inward
'  start label at same place, but line up each character position orthogonal to 1st line

_DEST keepingd&

END SUB


FUNCTION CheckBunch (px, py, lodSubset() AS LONG)
' this is the shortcut function
' rather maintain permanent copies of point, line and/or mask data for faster performance

np = UBOUND(lodSubset, 1)
REDIM CALM_linedat(0 TO np + 1, 0 TO 3) AS SINGLE

pdLineUpPoints lodSubset(), CALM_linedat()
GenerateShapeMask maskhandle&, lodSubset(), CALM_linedat(), 0, 0 'can replace 0 with offset variables to copy values
CheckBunch = pdPointCheck(px, py, CALM_linedat())

_FREEIMAGE maskhandle&

END FUNCTION


FUNCTION CheckPair (pairslayout() AS LONG, idx, px, py)
' tests if the point px,py is within the box formed by a point pair

CheckPair = 0
idx2 = (idx - 1) * 2
IF idx2 + 1 > UBOUND(pairslayout, 1) OR idx2 < LBOUND(pairslayout, 1) THEN EXIT FUNCTION

IF px >= pairslayout(idx2, 0) AND px <= pairslayout(idx2 + 1, 0) AND py >= pairslayout(idx2, 1) AND py <= pairslayout(idx2 + 1, 1) THEN
  CheckPair = -1
END IF

END FUNCTION


FUNCTION ReadPoints% (pointdata() AS LONG)
' use the format [DATA #points, x1, y1, x2, y2, ...] for providing point data
READ dct

FOR i = 0 TO dct - 1
  READ pointdata(i, 0), pointdata(i, 1)
NEXT i

ReadPoints% = dct - 1

END FUNCTION


FUNCTION LayerHue## (Arg1 AS LONG, Arg2 AS LONG)
 LayerHue## = __Pass2##(Arg1, Arg2)
END FUNCTION

FUNCTION __Pass2## (Arg1 AS LONG, Arg2 AS LONG)

DIM buf##, a1byt%%(0 TO 3), a2byt%%(0 TO 3)

DEF SEG = VARSEG(Arg1)
FOR i = 0 TO 3
 a1byt%%(i) = PEEK(VARPTR(Arg1) + i)
NEXT i
DEF SEG = VARSEG(Arg2)
FOR i = 0 TO 3
 a2byt%%(i) = PEEK(VARPTR(Arg2) + i)
NEXT i

DEF SEG = VARSEG(buf##)
FOR i = 0 TO 3
 POKE VARPTR(buf##) + i, a1byt%%(i)
NEXT i
FOR i = 4 TO 7
 POKE VARPTR(buf##) + i, a2byt%%(-4 + i)
NEXT i
POKE VARPTR(buf##) + 9, -1

__Pass2## = buf##

END FUNCTION


FUNCTION __Get2 (buf##, Arg1 AS LONG, Arg2 AS LONG)

DIM testbyt%%, a1byt%%(0 TO 3), a2byt%%(0 TO 3)

DEF SEG = VARSEG(buf##)
testbyt%% = PEEK(VARPTR(buf##) + 9)

IF testbyt%% = -1 THEN
 DEF SEG = VARSEG(buf##)
 FOR i = 0 TO 3
  a1byt%%(i) = PEEK(VARPTR(buf##) + i)
  a2byt%%(i) = PEEK(VARPTR(buf##) + 4 + i)
 NEXT i

 DEF SEG = VARSEG(Arg1)
 FOR i = 0 TO 3
  POKE VARPTR(Arg1) + i, a1byt%%(i)
 NEXT i
 DEF SEG = VARSEG(Arg2)
 FOR i = 0 TO 3
  POKE VARPTR(Arg2) + i, a2byt%%(i)
 NEXT i
 __Get2 = -1

ELSE
 Arg1 = CLNG(buf##)
 __Get2 = 0
 EXIT FUNCTION

END IF

END FUNCTION

'$INCLUDE:'polydetect.bas'

polydetect.bas
Code: [Select]
'polydetect                                        Version 1.00

' SYNTAX
' to init check -----
'      pdLineUpPoints pointdat(), linedat()  ' output will be received in these 3 arrays
'      GenerateShapeMask linedat(np + 1, 1), linedat(np + 1, 2), maskhandle&, pointdat(), linedat()
'
' to exec check -----
'      decide% = PDPointCheck(x, y, linedat()) ' i.e. check point x, y returning -1 if inside the shape

' (init step may be skipped if a mask image is available for use:
'             the mask image should use all white points for test = true, and color 0 for test = false
'             to use your image-
'                 1. dim an 2 dimension array x(0, 2) as a SINGLE and set the element 0, 0 to the handle of the mask
'                 2. if your mask origin doesn't coincide with the screen origin, set elements 0, 1
'                 and 0, 2 to the x and y offset values
'                     more than single shapes may be scanned in this manner)

' structure of arrays - copy these for each shape you make
'        pointdat&(q%, 1)     : an array of points (x,y coord); only 0 and 1 used; q% must be 0 to number of points - 1
'        linedat!(q% + 1, 3)  : contains slope in 0, const in 1, and 2 will be -1 or 1 (see below)
'
'   EXAMPLE:
'            REDIM Mypointdat(16, 2) AS LONG
'            REDIM Mylinedat(17, 3) AS SINGLE

'to do:
'  reexamine pdLineShapeChk and test GenerateShapeMaskDebug
'  fix- add additional fill in case of stranded pixels


SUB pdLineUpPoints (pointdat() AS LONG, linedat() AS SINGLE)
' linedat values are calculated here
' point data will be altered if > 2 consecutive points found along any line (!)
' both pointdat() and linedat() should be dynamic arrays

  yy = 0

  DIM oriinv AS INTEGER '   note- the line at which convexity turns into concavity will be 0 and v.v.

  pcount = UBOUND(pointdat, 1) ' pcount = num points beside the originating point (elsewhere as np)
  oriinv = 0

  flagrecalcoi = 0
  FOR i = 0 TO pcount ' note: actual pcount may decrease while looping
    'yy = yy + 1 ' diag
    ' set up ip<-prev index ; is<-successive index ; is2<-next successive index  ( i being the current point )
    ip = i - 1: IF ip = -1 THEN ip = pcount
    is = i + 1: IF is > pcount THEN is = 0
    is2 = i + 2: IF is2 > pcount THEN is2 = is2 - pcount - 1

    ' goal: store the coefficients for the line connecting i and is points in linedat; determine concavity of each line
    'linedat(i, 0) = (pointdat(is, 1) - pointdat(is, 1)) / (pointdat(i, 0) - pointdat(i, 0)) ' slope eqn
    term = (pointdat(is, 0) - pointdat(i, 0)): IF pointdat(is, 1) < pointdat(i, 1) THEN coterm = -1 ELSE coterm = 0
    IF term = 0 THEN
      term = .000005 'avoiding /0
      IF coterm THEN term = -term ' mark all vertical lines as having a high (+) slope
    END IF
    linedat(i, 0) = (pointdat(is, 1) - pointdat(i, 1)) / term 'line slope
    linedat(i, 1) = pointdat(i, 1) - linedat(i, 0) * pointdat(i, 0) ' constant term

    'check for consecutive points on the same line - important since that can mess up the angle-type calc
    GOSUB getslopeeqv
    IF i > 0 AND slopeeqvcheck THEN
      'current point discovered to be on the same line as previous
      ' will cull the intermediate point
      FOR i2 = i TO pcount - 1
         pointdat(i2, 0) = pointdat(i2 + 1, 0)
         pointdat(i2, 1) = pointdat(i2 + 1, 1)
      NEXT i2
      pcount = pcount - 1
      i = i - 1 ' will need to recheck the same index with its new values
      IF i >= pcount THEN EXIT FOR '  will stop looping if that was the final point
      flagrecalcoi = -1
    ELSE
    ' if all points so far are good, proceed with calculating faceing and angle-type (,2 & ,3)
      IF NOT flagrecalcoi THEN
        ' pointdat(i,1) = linedat(i,0) * pointdat(i,0) + linedat(i,1) ' line eqn
        ' test whether the previous point lies above line or below (g1)
        '  & whether the is2 point lies above line or below (g2)
        IF pointdat(ip, 1) >= linedat(i, 0) * pointdat(ip, 0) + linedat(i, 1) THEN g1 = -1 ELSE g1 = 0
        IF pointdat(is2, 1) >= linedat(i, 0) * pointdat(is2, 0) + linedat(i, 1) THEN g2 = -1 ELSE g2 = 0

        ' linedat (i, 2) is determined in conj. with the angle type (,3) value
        IF g1 <> g2 THEN oriinv = oriinv XOR -1
        linedat(i, 3) = NOT oriinv
        ' linedat(i, 2) = 1 means greater y .: test below line
        IF g2 = linedat(i, 3) THEN linedat(i, 2) = 1 ELSE linedat(i, 2) = -1
      END IF
    END IF

    IF i >= pcount THEN EXIT FOR
  NEXT i

  numdeletes = 0
' check the point that was skipped in the main loop
  i = 0
  ip = pcount
  GOSUB getslopeeqv
  IF slopeeqvcheck THEN
    FOR i = 1 TO pcount
       pointdat(i - 1, 0) = pointdat(i, 0)
       pointdat(i - 1, 1) = pointdat(i, 1)
       linedat(i - 1, 0) = linedat(i, 0)
       linedat(i - 1, 1) = linedat(i, 1)
    NEXT i
    pcount = pcount - 1
    flagrecalcoi = -1
  END IF

'PRINT "yy; fl= "; yy; "  "; flagrecalcoi '  diag
 IF flagrecalcoi THEN '  points were removed -> all ld,2 and ld,3 need to be recalculated
  oriinv = 0
    FOR i = 0 TO pcount
    ip = i - 1: IF ip = -1 THEN ip = pcount
    'is = i + 1: IF is > pcount THEN is = 0  ' (not used)
    is2 = i + 2: IF is2 > pcount THEN is2 = is2 - pcount - 1

    IF pointdat(ip, 1) >= linedat(i, 0) * pointdat(ip, 0) + linedat(i, 1) THEN g1 = -1 ELSE g1 = 0
    IF pointdat(is2, 1) >= linedat(i, 0) * pointdat(is2, 0) + linedat(i, 1) THEN g2 = -1 ELSE g2 = 0
    IF g1 <> g2 THEN oriinv = oriinv XOR -1
    linedat(i, 3) = NOT oriinv
    IF g2 = linedat(i, 3) THEN linedat(i, 2) = 1 ELSE linedat(i, 2) = -1
  NEXT i
 END IF

  ArtificialPreserveL pointdat(), 0, pcount ' resizes point array if needed

'  start inside-test
'      if initial line's orientation properties were inverted, resulting shape will be corrupt
'  method: take leftmost point (if multiple, pick highest
'      leftmost) & compare slopes of lines entering that point
'      if test true, (see below)

  getleft = 0
  FOR i = 1 TO pcount
    IF pointdat(i, 0) < pointdat(getleft, 0) THEN getleft = i
    IF pointdat(i, 0) = pointdat(getleft, 0) THEN
      IF pointdat(i, 1) < pointdat(getleft, 1) THEN getleft = i
    END IF
  NEXT i

  IF getleft = 0 THEN getleftP = pcount ELSE getleftP = getleft - 1
  IF linedat(getleft, 0) > linedat(getleftP, 0) THEN planedirec = 0 ELSE planedirec = -1 ' clockws else cclockws
  IF (planedirec = 0 AND linedat(getleft, 2) = 1) OR (planedirec = -1 AND linedat(getleft, 2) = -1) THEN

    'test true, therefore reverse test direction and orientation property for each line
    FOR i = 0 TO pcount
      is = i + 1: IF is > pcount THEN is = 0
      ip = i - 1: IF ip < 0 THEN ip = pcount
      linedat(i, 2) = -linedat(i, 2)
      linedat(i, 3) = linedat(i, 3) XOR -1
    NEXT i

  END IF
' ]...inside-test done

  ArtificialPreserveS linedat(), 0, pcount + 1 '  resize lines array if needed

EXIT SUB

getslopeeqv:
slopeeqvcheck = 0
slopeeqvcheckthreshold = .0000015
'if (short line) slopeeqvcheckthreshold = .15 ' .162 ' .182
'aas = ABS(ATN(linedat(i, 0)) - ATN(linedat(ip, 0)))
ge_i = ATN(linedat(i, 0)): ge_ip = ATN(linedat(ip, 0))
IF ge_i < 0 THEN ge_i = 180 + ge_i
IF ge_ip < 0 THEN ge_ip = 180 + ge_ip
''IF ge_i < 3 THEN slopeeqvcheckthreshold = .0005
aas = ABS(ge_i - ge_ip)
'IF 3.14159 - aas < slopeeqvcheckthreshold OR aas < slopeeqvcheckthreshold THEN slopeeqvcheck = -1
IF aas < slopeeqvcheckthreshold THEN slopeeqvcheck = -1

RETURN


END SUB


SUB GenerateShapeMask (chk_pic AS LONG, pointdat() AS LONG, linedat() AS SINGLE, xo AS SINGLE, yo AS SINGLE)
' creates a simple on/off mask, for the pointcheck function to test against
' method: draws shape, then loop through each line executing a paint at 1 pix off its center
'  offset coordinates are used, allowing smaller images to be generated; user may opt to use 0,0 offset for their own masks
RegChkColor& = _RGBA(255, 255, 255, 255)

np = UBOUND(pointdat, 1)

'find out offsets to reduce image size - for mem optimization
getleft = 0: getright = 0: gettop = 0: getbottom = 0 ' will change from index to actual value
FOR i = 1 TO np
  IF pointdat(i, 0) < pointdat(getleft, 0) THEN getleft = i
  IF pointdat(i, 0) > pointdat(getright, 0) THEN getright = i
  IF pointdat(i, 1) < pointdat(gettop, 1) THEN gettop = i
  IF pointdat(i, 1) > pointdat(getbottom, 1) THEN getbottom = i
NEXT i
getleft = pointdat(getleft, 0): getright = pointdat(getright, 0): gettop = pointdat(gettop, 1): getbottom = pointdat(getbottom, 1)
xo = getleft: yo = gettop

keepingDest& = _DEST
chk_pic = _NEWIMAGE(getright - getleft + 1, getbottom - gettop + 1, 32)
_DEST chk_pic
CLS , 0

'draw in the outline of our shape
FOR i = 0 TO np
  is = i + 1: IF is > np THEN is = 0
  LINE (pointdat(i, 0) - getleft, pointdat(i, 1) - gettop)-(pointdat(is, 0) - getleft, pointdat(is, 1) - gettop), RegChkColor&
NEXT i

'paint all the inside of our shape
FOR i = 0 TO np
  is = i + 1: IF is > np THEN is = 0
px = -xo + (pointdat(i, 0) + pointdat(is, 0)) / 2 + 1
py = -yo + (pointdat(i, 1) + pointdat(is, 1)) / 2 + 1
 IF linedat(i, 2) = 1 THEN
   IF linedat(i, 0) > 0 THEN 'further adjust px but not py
    px = px - 2
   END IF
 ELSE 'further adjust py and maybe px
   py = py - 2
   IF linedat(i, 0) < 0 THEN 'further adjust px
    px = px - 2
   END IF
 END IF
 PAINT (px, py), RegChkColor&, RegChkColor&
NEXT i
' IMPLEMENT - additional fill, for stranded pixels which PAINT can miss
'FOR x = 1 TO _WIDTH(chk_pic) - 1
'  FOR y = 1 TO _HEIGHT(chk_pic) - 2
'     IF NOT POINT(x, y) THEN
    'u'   IF POINT(x, y + 1) = &HFFFFFFFF AND POINT(x, y - 1) = &HFFFFFFFF THEN PSET (x, y), RegChkColor&
'     END IF
'  NEXT y
'NEXT x

_DEST keepingDest&
linedat(np + 1, 1) = xo
linedat(np + 1, 2) = yo
linedat(np + 1, 0) = CSNG(chk_pic)
IF chk_pic <> CLNG(linedat(np + 1, 0)) THEN ERROR

END SUB


SUB GenerateShapeMaskDebug (chk_pic AS LONG, pointdat() AS LONG, linedat() AS SINGLE, xo AS SINGLE, yo AS SINGLE)
' calling PDLineShapeChk a few times, could be faster than looping through each line
RegChkColor& = _RGBA(255, 255, 255, 255)

np = UBOUND(pointdat, 1)

'find out offsets to reduce image size - for mem optimization
getleft = 0: getright = 0: gettop = 0: getbottom = 0 ' will change from index to actual value
FOR i = 1 TO np
  IF pointdat(i, 0) < pointdat(getleft, 0) THEN getleft = i
  IF pointdat(i, 0) > pointdat(getright, 0) THEN getright = i
  IF pointdat(i, 1) < pointdat(gettop, 1) THEN gettop = i
  IF pointdat(i, 1) > pointdat(getbottom, 1) THEN getbottom = i
NEXT i
getleft = pointdat(getleft, 0): getright = pointdat(getright, 0): gettop = pointdat(gettop, 1): getbottom = pointdat(getbottom, 1)
xo = getleft: yo = gettop

keepingDest& = _DEST
chk_pic = _NEWIMAGE(getright - getleft + 1, getbottom - gettop + 1, 32)
_DEST chk_pic
CLS , 0

'draw in the outline of our shape
FOR i = 0 TO np
  is = i + 1: IF is > np THEN is = 0
  LINE (pointdat(i, 0) - getleft, pointdat(i, 1) - gettop)-(pointdat(is, 0) - getleft, pointdat(is, 1) - gettop), RegChkColor&
NEXT i

'paint all the inside of our shape
pa = 0
FOR x = 1 TO _WIDTH(chk_pic) - 1
  FOR y = 1 TO _HEIGHT(chk_pic) - 2
    IF pa < 30 THEN '   pick some points inside the shape to run fill command on
     IF pdLineShapeChk(x + getleft, y + gettop, linedat()) THEN
       ' checked original coordinates, but paint using offset coordinates
       PAINT (x, y), RegChkColor&, RegChkColor&
       pa = pa + 1
       y = y + 4 ' or some rnd number
     END IF
     x = x + 1 ' effectively make it STEP 2
     y = y + 1
    ELSE
     IF pa = 30 THEN
       x = 1
       y = 1
       pa = pa + 1
     END IF
     ' additional fill, for stranded pixels which PAINT can miss
     'IF NOT POINT(x, y) THEN
    'u'   IF POINT(x, y + 1) = &HFFFFFFFF AND POINT(x, y - 1) = &HFFFFFFFF THEN PSET (x, y), RegChkColor&
     'END IF
    END IF

  NEXT y
NEXT x

_DEST keepingDest&
linedat(np + 1, 1) = xo
linedat(np + 1, 2) = yo
linedat(np + 1, 0) = CSNG(chk_pic)
IF chk_pic <> CLNG(linedat(np + 1, 0)) THEN ERROR

END SUB


FUNCTION pdLineShapeCheck (x AS SINGLE, y AS SINGLE, linedat() AS SINGLE)

'  runs an incomplete check by itself, for normal use GenerateShapeMask and PDPointCheck combo
'  like pdPointCheck but using geometric formulas instead of an image mask

linetest = -1 ' true while the point at (x, y) is within all the lines

np = UBOUND(linedat, 1) - 1

varfinpt = np
FOR i3 = 0 TO np: IF i3 > varfinpt THEN EXIT FOR

  IF linedat(i3, 3) THEN
    IF linedat(i3, 2) = 1 THEN
      linetest = linetest AND (y > linedat(i3, 0) * x + linedat(i3, 1))
    ELSEIF linedat(i3, 2) = -1 THEN
      linetest = linetest AND (y < linedat(i3, 0) * x + linedat(i3, 1))
    END IF
  ELSE
    GOSUB ors ' check of a string of innies, actually an AND check on the reverse of the lines
    linetest = linetest AND orstest
  END IF

NEXT i3

pdLineShapeChk = linetest
EXIT FUNCTION

ors: 'sub DoLineChecks:longors
orstest = -1

bini = i3 ' set first innie

fcheck = 0 ' this check means we've looped back through to 0  /through every point/line
ns = np + 1
FOR ifo = bini TO ns
  IF ifo > np THEN ifo = ifo - ns: fcheck = -1 ' shouldn't be a case
  IF linedat(ifo, 3) THEN lini = ifo: EXIT FOR
NEXT ifo

' mod first innie if needed
IF bini = 0 THEN
  FOR chkbini = np TO 0 STEP -1
    IF linedat(chkbini, 3) THEN
      EXIT FOR
    ELSE
      bini = chkbini
      varfinpt = chkbini - 1
      fcheck = -1
    END IF
  NEXT chkbini
END IF
yy = y: orsstr$ = orsstr$ + STR$(bini) + STR$(lini)

IF fcheck THEN lini1 = lini + ns ELSE lini1 = lini
FOR i4 = bini TO lini1 '  main part of OR check
  IF i4 > np THEN i4 = i4 - ns
  IF linedat(i4, 2) = 1 THEN
    orstest = orstest AND (y < linedat(i4, 0) * x + linedat(i4, 1))
  ELSEIF linedat(i4, 2) = -1 THEN
    orstest = orstest AND (y > linedat(i4, 0) * x + linedat(i4, 1))
  END IF
  IF i4 = lini THEN EXIT FOR
NEXT i4

i3 = lini ' note:  is incremented 1 after return

orstest = NOT orstest 'because all ands being true = fail

RETURN

END FUNCTION


FUNCTION pdPointCheck (x AS SINGLE, y AS SINGLE, chkdat() AS SINGLE)
' may be used with generated masks usually by passing in the linedat() array
'  or directly make a 2 dim array and set (0,0) = your image handle (offsets at 0,1 and 0,2 )
np = UBOUND(chkdat, 1) - 1

DIM chk_pic AS LONG
chk_pic = CLNG(chkdat(np + 1, 0))
xo = chkdat(np + 1, 1): yo = chkdat(np + 1, 2)

keepingSrc& = _SOURCE
_SOURCE chk_pic

x1 = x - xo: y1 = y - yo
IF POINT(x1, y1) THEN pdPointCheck = -1
IF x1 < 0 OR y1 < 0 THEN pdPointCheck = 0
IF x1 + 1 > _WIDTH(chk_pic) OR y1 + 1 > _HEIGHT(chk_pic) THEN pdPointCheck = 0
_SOURCE keepingSrc&

END FUNCTION


SUB ArtificialPreserveL (ar() AS LONG, newFirstLBound, newFirstUBound) 'type name appears 3 times in this sub, and every instance must match

ol = LBOUND(ar, 1): ou = UBOUND(ar, 1)
IF ol = newFirstLBound AND ou = newFirstUBound THEN EXIT SUB ' skip, if acidentally calling when not needed

DIM new_ar(newFirstLBound TO newFirstUBound, LBOUND(ar, 2) TO UBOUND(ar, 2)) AS LONG


ALTnewFirstUBound = newFirstUBound
IF newFirstUBound > ou THEN ALTnewFirstUBound = ou ' here assuming unchanged lo bound
FOR i = newFirstLBound TO ALTnewFirstUBound
 FOR i2 = LBOUND(ar, 2) TO UBOUND(ar, 2)
   new_ar(i, i2) = ar(ol + i - newFirstLBound, i2)
 NEXT i2
NEXT i

REDIM ar(newFirstLBound TO newFirstUBound, LBOUND(new_ar, 2) TO UBOUND(new_ar, 2)) AS LONG

FOR i = newFirstLBound TO newFirstUBound
 FOR i2 = LBOUND(ar, 2) TO UBOUND(ar, 2)
   ar(i, i2) = new_ar(i, i2)
 NEXT i2
NEXT i

END SUB


SUB ArtificialPreserveS (ar() AS SINGLE, newFirstLBound, newFirstUBound) 'type name appears 3 times in this sub, and every instance must match

ol = LBOUND(ar, 1): ou = UBOUND(ar, 1)
IF ol = newFirstLBound AND ou = newFirstUBound THEN EXIT SUB ' skip, if acidentally calling when not needed

DIM new_ar(newFirstLBound TO newFirstUBound, LBOUND(ar, 2) TO UBOUND(ar, 2)) AS SINGLE


ALTnewFirstUBound = newFirstUBound
IF newFirstUBound > ou THEN ALTnewFirstUBound = ou ' here assuming unchanged lo bound
FOR i = newFirstLBound TO ALTnewFirstUBound
 FOR i2 = LBOUND(ar, 2) TO UBOUND(ar, 2)
   new_ar(i, i2) = ar(ol + i - newFirstLBound, i2)
 NEXT i2
NEXT i

REDIM ar(newFirstLBound TO newFirstUBound, LBOUND(new_ar, 2) TO UBOUND(new_ar, 2)) AS SINGLE

FOR i = newFirstLBound TO newFirstUBound
 FOR i2 = LBOUND(ar, 2) TO UBOUND(ar, 2)
   ar(i, i2) = new_ar(i, i2)
 NEXT i2
NEXT i

END SUB

Please note the polydetect component was intended to be separate, may be only semi complete and generally is subject to change.  This affects pdLineUpPoints, GenerateShapeMask and PDPointCheck functionality.

If you get a file not found error, but have placed all the files correctly named where they should be, it's not my fault it's qb64's. an easy workaround is found in this thread


What it allows you to do:
Define graphical objects in your program via coordinates or a coded picture
Intuitively link graphical objects with pointing devices
Set up striking visuals(tm) and interface with every single pixel(r)!

the perceptive might recognize it as a rehash as it were of my layouter add-in from this thread, with a few tweaks and adds.  basic documentation is in the big file

Usage will look like
Code: [Select]
'$INCLUDE:'calmcompinit.bas'
[your code]
ReadLayout a(), "schema001.bmp", 0
ShowBox a(), 3, "I'm box 3", 0, _DEST
[your code]
IF CheckPair (a(), 3, _MOUSEX, _MOUSEY) THEN PRINT "You clicked the 3rd box"
[your code]
'$INCLUDE:'calmcompfunc.bas'

Second example - interface component using mouse-linked orbs:
Code: [Select]
'$INCLUDE:'calmcompinit.bas'

bgScr& = _NEWIMAGE(800, 600, 32)

SCREEN bgScr&

DIM huedropmain(-1 TO 0) AS LONG, huedropaux(-1 TO 2) AS LONG
DIM gfxgumdrop(6) AS LONG
gumdropX = 500: gumdropY = 350 ' set position for gumdrop interface
mdrad = 108
diagdelay = 0: diagdelay = 0 ' .075
animswitchstartframe = 18
CONST pi = 3.1415

dropstate%% = 0: framestate%% = 1 ' init values

REDIM DropA(47, 2) AS LONG, DropB(23, 2) AS LONG, Drop1(47, 2) AS LONG, Drop2(47, 2) AS LONG, Drop3(47, 2) AS LONG
REDIM DropAgeo(48, 3) AS SINGLE, DropBgeo(24, 3) AS SINGLE, Drop1geo(48, 3) AS SINGLE, Drop2geo(48, 3) AS SINGLE, Drop3geo(48, 3) AS SINGLE

GOSUB linkdrops
GOSUB drawdrops

' note display delay below near line 71
animateclick = 1000 ' lower value for faster animations

DO: DO WHILE _MOUSEINPUT: LOOP
 plmb = lmb: lmb = _MOUSEBUTTON(1)
 prmb = rmb: rmb = _MOUSEBUTTON(2)
 cx = _MOUSEX: cy = _MOUSEY

' v v v --this catch routine is specific to the event 'animswitch'
IF (c## MOD animateclick = animswitch.time##) AND (animswitch > 0) THEN
  animswitch = animswitch - 1
  IF animswitch = 0 THEN flaganimswitch = -1
END IF

IF (plmb IMP lmb) = 0 THEN
 ' check all targets for clicks
 IF PDPointCheck(cx, cy, DropBgeo()) THEN
   IF animswitch > 0 THEN GOTO clickstried ' suppress inner drop click reading while animating
   animswitch = animswitchstartframe: animswitch.time## = c## MOD animateclick
clickstried:
  ELSE
   IF PDPointCheck(cx, cy, DropAgeo()) THEN
    IF dropstate%% THEN PRINT "b" ELSE PRINT "a"
   ELSE
    IF dropstate%% THEN
       IF PDPointCheck(cx, cy, Drop1geo()) THEN PRINT "yay 1!"
       IF PDPointCheck(cx, cy, Drop2geo()) THEN PRINT "yay 2!"
       IF PDPointCheck(cx, cy, Drop3geo()) THEN PRINT "yay 3!"
    END IF
   END IF

 END IF
END IF

IF (animswitch > 0 OR flaganimswitch) AND (framestate%% <> animswitch) THEN
   IF flaganimswitch THEN flaganimswitch = 0: dropstate%% = dropstate%% XOR -1: whichframe$ = ""

   CLS
   GOSUB drawdrops
   framestate%% = animswitch

   'PRINT whichframe$
   _DELAY diagdelay

END IF

c## = c## + 1
IF c## MOD 600 = 0 THEN _DISPLAY ' smoothens display

IF (prmb IMP rmb) = 0 THEN animswitch.time## = c## MOD animateclick

LOOP UNTIL INKEY$ = CHR$(27) 'or  _MOUSEBUTTON(2)
_AUTODISPLAY

END

linkdrops:
seprate = 4 ' defined twice
bdrad = INT(mdrad * .354)
FOR i = 0 TO 47
 DRAW "B M" + STR$(gumdropX) + "," + STR$(gumdropY) + "TA" + STR$(i * 8) + " B U" + STR$(mdrad + 1)
 DropA(i, 0) = POINT(0): DropA(i, 1) = POINT(1)
 IF i MOD 2 = 0 THEN
  DRAW "B M" + STR$(gumdropX + bdrad) + "," + STR$(gumdropY + bdrad) + "TA" + STR$(i / 2 * 16) + " B U" + STR$(mdrad \ 2)
  DropB(i / 2, 0) = POINT(0): DropB(i / 2, 1) = POINT(1)
 END IF
 DRAW "B M" + STR$(INT(gumdropX - mdrad * SIN(.2 * pi / seprate))) + "," + STR$(INT(gumdropY - mdrad * COS(.2 * pi / seprate))) + "TA" + STR$(i * 8) + " B U" + STR$(mdrad \ 3)
 Drop1(i, 0) = POINT(0): Drop1(i, 1) = POINT(1)
 DRAW "B M" + STR$(INT(gumdropX - mdrad * SIN(1.2 * pi / seprate))) + "," + STR$(INT(gumdropY - mdrad * COS(1.2 * pi / seprate))) + "TA" + STR$(i * 8) + " B U" + STR$(mdrad \ 3)
 Drop2(i, 0) = POINT(0): Drop2(i, 1) = POINT(1)
 DRAW "B M" + STR$(INT(gumdropX - mdrad * SIN(2.2 * pi / seprate))) + "," + STR$(INT(gumdropY - mdrad * COS(2.2 * pi / seprate))) + "TA" + STR$(i * 8) + " B U" + STR$(mdrad \ 3)
 Drop3(i, 0) = POINT(0): Drop3(i, 1) = POINT(1)
NEXT i

PDLineUpPoints DropA(), DropAgeo()
PDLineUpPoints DropB(), DropBgeo()
PDLineUpPoints Drop1(), Drop1geo()
PDLineUpPoints Drop2(), Drop2geo()
PDLineUpPoints Drop3(), Drop3geo()
GenerateShapeMask DropAgeo(UBOUND(DropAgeo, 1), 0), DropA(), DropAgeo(), 0, 0
GenerateShapeMask DropBgeo(UBOUND(DropBgeo, 1), 0), DropB(), DropBgeo(), 0, 0
GenerateShapeMask Drop1geo(UBOUND(Drop1geo, 1), 0), Drop1(), Drop1geo(), 0, 0
GenerateShapeMask Drop2geo(UBOUND(Drop2geo, 1), 0), Drop2(), Drop2geo(), 0, 0
GenerateShapeMask Drop3geo(UBOUND(Drop3geo, 1), 0), Drop3(), Drop3geo(), 0, 0

RETURN

drawdrops:
whichframe$ = whichframe$ + STR$(animswitch)

huedropmain(0) = _RGB(150, 40, 45): huedropmain(-1) = _RGB(190, 205, 20)
huedropaux(-1) = _RGB32(120, 120, 120): huedropaux(0) = _RGB32(210, 80, 40): huedropaux(1) = _RGB32(150, 40, 175): huedropaux(2) = _RGB32(30, 20, 150) '_RGB32(40, 80, 210)

' if first time, create some images for the gummy graphics
keepingdest& = _DEST
FOR subi = 0 TO 6
 IF gfxgumdrop(subi) >= -1 THEN
   gfxgumdrop(subi) = _NEWIMAGE(mdrad * 2 + 1, mdrad * 2 + 1, 32)
   _DEST gfxgumdrop(subi)
   SELECT CASE subi
     CASE 0: CIRCLE (mdrad, mdrad), mdrad, huedropmain(0), , , 1: PAINT (mdrad, mdrad), huedropmain(0), huedropmain(0)
     CASE 1: CIRCLE (mdrad, mdrad), mdrad, huedropmain(-1), , , 1: PAINT (mdrad, mdrad), huedropmain(-1), huedropmain(-1)
     CASE 4: CIRCLE (mdrad, mdrad), mdrad / 3, huedropaux(-1), , , 1
       CIRCLE (mdrad, mdrad), mdrad / 4.3, huedropaux(0), , , 1: PAINT (mdrad, mdrad), huedropaux(0), huedropaux(0)
     CASE 5: CIRCLE (mdrad, mdrad), mdrad / 3, huedropaux(-1), , , 1
       CIRCLE (mdrad, mdrad), mdrad / 4.3, huedropaux(1), , , 1: PAINT (mdrad, mdrad), huedropaux(1), huedropaux(1)
     CASE 6: CIRCLE (mdrad, mdrad), mdrad / 3, huedropaux(-1), , , 1
       CIRCLE (mdrad, mdrad), mdrad / 4.3, huedropaux(2), , , 1: PAINT (mdrad, mdrad), huedropaux(2), huedropaux(2)
   END SELECT
 END IF
NEXT subi
_DEST keepingdest&

' if activated, draw in mini drops
IF dropstate%% THEN
   seprate = 4
   FOR subi = 0 TO 2
    'CIRCLE (gumdropX - mdrad * SIN((subi + .2) * pi / seprate), gumdropY - mdrad * COS((subi + .2) * pi / seprate)), mdrad / 3, huedropaux(subi)
    _PUTIMAGE (gumdropX - mdrad - mdrad * SIN((subi + .2) * pi / seprate), gumdropY - mdrad - mdrad * COS((subi + .2) * pi / seprate)), gfxgumdrop(4 + subi)
   NEXT subi
END IF

' draw the big drop
_PUTIMAGE (gumdropX - mdrad, gumdropY - mdrad), gfxgumdrop(ABS(dropstate%% XOR -1))

IF animswitch = 0 THEN ' thus, for any non-animated frame paint a standard inner drop
FOR subi = 2 TO 3
 _DEST gfxgumdrop(subi)
 CLS , 0
 IF subi = 2 THEN hh = 0 ELSE hh = -1
 CIRCLE (mdrad, mdrad), mdrad / 2, huedropmain(hh), , , 1: PAINT (mdrad, mdrad), huedropmain(hh), huedropmain(hh)
NEXT subi
_DEST keepingdest&

_PUTIMAGE (gumdropX - mdrad + mdrad * .354, gumdropY - mdrad + mdrad * .354), gfxgumdrop(2 + ABS(dropstate%%))

ELSE ' ...while animated frames will have the inner drop looking different
tmpthreshfr = 9
 _DEST gfxgumdrop(2 + ABS(dropstate%%))
  CLS , 0
  CIRCLE (mdrad, mdrad), mdrad * (1 / 2 + ((animswitchstartframe + 1) - animswitch) / (2 * animswitchstartframe)), huedropmain(dropstate%%), , , 1: PAINT (mdrad, mdrad), huedropmain(dropstate%%), huedropmain(dropstate%%)
 _DEST gfxgumdrop(2 + ABS(dropstate%% XOR -1))
  CLS , 0
  CIRCLE (mdrad, mdrad), mdrad * ((tmpthreshfr - animswitch) / (2 * (tmpthreshfr - 1))), huedropmain(dropstate%% XOR -1), , , 1: PAINT (mdrad, mdrad), huedropmain(dropstate%% XOR -1), huedropmain(dropstate%% XOR -1)
 _DEST keepingdest&

 dropdist% = .707 * (mdrad - mdrad * (.5 + ((animswitchstartframe + 1) - animswitch) / (2 * animswitchstartframe)))
 babydropdist% = .707 * (1.5 * mdrad - mdrad * (.5 + (tmpthreshfr - animswitch) / (2 * (tmpthreshfr - 1)))) - 3 * dropdist%
 _PUTIMAGE (gumdropX - mdrad + dropdist%, gumdropY - mdrad + dropdist%), gfxgumdrop(2 + ABS(dropstate%%))
 IF animswitch < tmpthreshfr THEN _PUTIMAGE (gumdropX - mdrad + babydropdist%, gumdropY - mdrad + babydropdist%), gfxgumdrop(2 + ABS(dropstate%% XOR -1))
END IF

RETURN

'$INCLUDE:'calmcompfunc.bas'
« Last Edit: April 17, 2011, 05:39:14 AM by Muffinman »

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #1 on: January 03, 2011, 06:21:43 PM »
First example:
you are supposed to click on the shapes to make them change color
Code: [Select]
'$INCLUDE:'calmcompinit.bas'

SCREEN _NEWIMAGE(800, 600, 32)
GOSUB clearscr

FOR i = 0 TO 3
scol(i) = i
NEXT i

REDIM colset&(3)
colset&(0) = _RGBA32(0, 0, 0, 48): colset&(1) = _RGBA32(150, 0, 75, 176): colset&(2) = _RGB32(215, 215, 0): colset&(3) = _RGB32(0, 75, 150)

REDIM MyShape_01(0 TO 1024, 0 TO 1) AS LONG
REDIM MyShape_02(0 TO 1024, 0 TO 1) AS LONG
REDIM MyShape_03(0 TO 1024, 0 TO 1) AS LONG
REDIM MyShape_04(0 TO 1024, 0 TO 1) AS LONG
readsiz = ReadPoints(MyShape_01())
ArtificialPreserveL MyShape_01(), 0, readsiz
readsiz = ReadPoints(MyShape_02())
ArtificialPreserveL MyShape_02(), 0, readsiz
readsiz = ReadPoints(MyShape_03())
ArtificialPreserveL MyShape_03(), 0, readsiz
readsiz = ReadPoints(MyShape_04())
ArtificialPreserveL MyShape_04(), 0, readsiz

REDIM MyShape_01_ld(0 TO UBOUND(MyShape_01, 1) + 1, 0 TO 3) AS SINGLE
REDIM MyShape_02_ld(0 TO UBOUND(MyShape_02, 1) + 1, 0 TO 3) AS SINGLE
REDIM MyShape_03_ld(0 TO UBOUND(MyShape_03, 1) + 1, 0 TO 3) AS SINGLE
REDIM MyShape_04_ld(0 TO UBOUND(MyShape_04, 1) + 1, 0 TO 3) AS SINGLE

PDLineUpPoints MyShape_01(), MyShape_01_ld()
PDLineUpPoints MyShape_02(), MyShape_02_ld()
PDLineUpPoints MyShape_03(), MyShape_03_ld()
PDLineUpPoints MyShape_04(), MyShape_04_ld()

GenerateShapeMask bleh&, MyShape_01(), MyShape_01_ld(), MyShape_01_ld(UBOUND(MyShape_01_ld), 1), MyShape_01_ld(UBOUND(MyShape_01_ld), 2)
GenerateShapeMask bleh&, MyShape_02(), MyShape_02_ld(), MyShape_02_ld(UBOUND(MyShape_02_ld), 1), MyShape_02_ld(UBOUND(MyShape_02_ld), 2)
GenerateShapeMask bleh&, MyShape_03(), MyShape_03_ld(), 0, 0
GenerateShapeMask bleh&, MyShape_04(), MyShape_04_ld(), 0, 0

'reposition shapes read from DATA
FOR i = 0 TO UBOUND(MyShape_01, 1)
ho = MyShape_01_ld(UBOUND(MyShape_01_ld), 1) - 50
vo = MyShape_01_ld(UBOUND(MyShape_01_ld), 2) - 50
   MyShape_01(i, 0) = MyShape_01(i, 0) - ho
   MyShape_01(i, 1) = MyShape_01(i, 1) - vo
NEXT i
FOR i = 0 TO UBOUND(MyShape_02, 1)
ho = MyShape_02_ld(UBOUND(MyShape_02_ld), 1) - 175
vo = MyShape_02_ld(UBOUND(MyShape_02_ld), 2) - 50
   MyShape_02(i, 0) = MyShape_02(i, 0) - ho
   MyShape_02(i, 1) = MyShape_02(i, 1) - vo
NEXT i
FOR i = 0 TO UBOUND(MyShape_03, 1)
ho = MyShape_03_ld(UBOUND(MyShape_03_ld), 1) - 350
vo = MyShape_03_ld(UBOUND(MyShape_03_ld), 2) - 50
   MyShape_03(i, 0) = MyShape_03(i, 0) - ho
   MyShape_03(i, 1) = MyShape_03(i, 1) - vo
NEXT i
FOR i = 0 TO UBOUND(MyShape_04, 1)
ho = MyShape_04_ld(UBOUND(MyShape_04_ld), 1) - 525
vo = MyShape_04_ld(UBOUND(MyShape_04_ld), 2) - 50
   MyShape_04(i, 0) = MyShape_04(i, 0) - ho
   MyShape_04(i, 1) = MyShape_04(i, 1) - vo
NEXT i

MyShape_01_ld(UBOUND(MyShape_01_ld, 1), 1) = 50: MyShape_01_ld(UBOUND(MyShape_01_ld, 1), 2) = 50
MyShape_02_ld(UBOUND(MyShape_02_ld, 1), 1) = 175: MyShape_02_ld(UBOUND(MyShape_02_ld, 1), 2) = 50
MyShape_03_ld(UBOUND(MyShape_03_ld, 1), 1) = 350: MyShape_03_ld(UBOUND(MyShape_03_ld, 1), 2) = 50
MyShape_04_ld(UBOUND(MyShape_04_ld, 1), 1) = 525: MyShape_04_ld(UBOUND(MyShape_04_ld, 1), 2) = 50
'done repositioning

GOSUB drawall

DO: DO WHILE _MOUSEINPUT: LOOP
 ik$ = INKEY$
 plmb = lmb: lmb = _MOUSEBUTTON(1)

 IF (plmb IMP lmb) = 0 THEN
     'COLOR _RGB(_RED(_DEFAULTCOLOR), _GREEN(_DEFAULTCOLOR) + 32, _BLUE(_DEFAULTCOLOR))
     cmd_redraw = 0
     IF CheckBunch(_MOUSEX, _MOUSEY, MyShape_01()) THEN scol(0) = scol(0) + 1: cmd_redraw = -1
     IF CheckBunch(_MOUSEX, _MOUSEY, MyShape_02()) THEN scol(1) = scol(1) + 1: cmd_redraw = -1
     IF CheckBunch(_MOUSEX, _MOUSEY, MyShape_03()) THEN scol(2) = scol(2) + 1: cmd_redraw = -1
     IF CheckBunch(_MOUSEX, _MOUSEY, MyShape_04()) THEN scol(3) = scol(3) + 1: cmd_redraw = -1
     'IF PDPointCheck(_MOUSEX, _MOUSEY, MyShape_01_ld()) THEN scol(0) = scol(0) + 1: cmd_redraw = -1 'alternative use
     'IF PDPointCheck(_MOUSEX, _MOUSEY, MyShape_02_ld()) THEN scol(1) = scol(1) + 1: cmd_redraw = -1
     ' ....

     IF cmd_redraw THEN GOSUB drawall

 END IF

 IF _MOUSEBUTTON(2) THEN COLOR _RGB(112, 96, 0)


LOOP UNTIL ik$ = CHR$(27)

END

clearscr:
CLS , _RGB(200, 0, 0)

FOR g = 1 TO 600 STEP 30
  LINE (0, g)-STEP(799, 15), _RGB(10, 190, 50), BF
NEXT g
RETURN

drawall:
'regularize scol's
FOR r = 0 TO 3
 IF scol(r) > 3 THEN scol(r) = scol(r) MOD 4
NEXT r

GOSUB clearscr

shapeCol& = colset&(scol(0))    ' _RGBA32(0,215, 0, 176) '_RGB32(150, 75, 0)
ShowBunch MyShape_01(), "", 5, LayerHue(_DEST, shapeCol&)
shapeCol& = colset&(scol(1))
ShowBunch MyShape_02(), "", 5, LayerHue(_DEST, shapeCol&)
shapeCol& = colset&(scol(2))
ShowBunch MyShape_03(), "", 5, LayerHue(_DEST, shapeCol&)
shapeCol& = colset&(scol(3))
ShowBunch MyShape_04(), "", 5, LayerHue(_DEST, shapeCol&)

RETURN

'shape data format = #points, x1, y1, x2, y2, ...
DATA 10,16,125,16,25,35,51,49,38,66,37,57,57,71,63,47,84,26,94,29,112
DATA 10,16,125,7,25,26,43,17,64,41,71,51,54,71,69,59,100,36,101,39,130
DATA 10,16,125,16,25,33,58,39,46,50,39,53,52,44,72,56,80,67,65,96,79
DATA 10,16,125,16,25,103,40,80,71,75,48,44,51,50,84,102,83,112,69,115,100


'$INCLUDE:'calmcompfunc.bas'

this example's sort of weak, but demonstrates how you can have clickings detected by whether you're actually pointing at a shape, not a crude rectangle containing the shape

I have a much better example in mind, but being somewhat loopy from work I'm going to leave that until later

Clippy

  • Hero Member
  • *****
  • Posts: 16446
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #2 on: January 03, 2011, 09:06:35 PM »
This section is for DECLARE LIBRARIES!

NOT $INCLUDE Libraries...

Ted
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

DarthWho

  • Hero Member
  • *****
  • Posts: 3854
  • Timelord of the Sith
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #3 on: January 03, 2011, 09:42:47 PM »
clippy does have a point here a include library is in pure qb64/qbxx code form and hence belongs with the rest of the pure qb64/qbxx stuff if you had a library that was say written in C or Python then you could put either links to the DLL or LIB in here or put the source code and specify the native language.
anything that is not pure qb64/qbxx code must be accessed through Declare [Dynamic] Library
the only exception is if you have a qb64 wrapper for a library you can post that here as well but $include libraries are the sort of library or wrapper to put here.
Rassilon: My lord Doctor; My lord Master; My lord DarthWho
The Doctor and the master at the same time :WHAT!?!?!

FastMath 1.1.0 released: http://dl.dropbox.com/u/12359848/fastmath.h

Clippy

  • Hero Member
  • *****
  • Posts: 16446
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #4 on: January 03, 2011, 10:39:18 PM »
WADDAYA MEAN I HAVE A POINT?

I DON'T NEED YOUR APPROVAL! Go play with the other monkeys!

QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
peace thread
« Reply #5 on: January 04, 2011, 05:43:17 AM »
now fellas... there's plenty of room here for all our libraries.  doesn't mean yours are in any way less special if you post them after me.  8)

DarthWho

  • Hero Member
  • *****
  • Posts: 3854
  • Timelord of the Sith
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #6 on: January 04, 2011, 05:46:43 AM »
I was providing clarification
you rarely have my approval ;D
Rassilon: My lord Doctor; My lord Master; My lord DarthWho
The Doctor and the master at the same time :WHAT!?!?!

FastMath 1.1.0 released: http://dl.dropbox.com/u/12359848/fastmath.h

Clippy

  • Hero Member
  • *****
  • Posts: 16446
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #7 on: January 04, 2011, 08:42:25 AM »
Looks like I'll be STUFFIN MUFFINS tonight!  ;D

Garth, I didn't NEED a paragraph to tell him what needed to be said. Apparently Galleon doesn't care anyhow...

QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #8 on: January 07, 2011, 01:42:53 AM »
I got sort of delayed making the muffin-tastic examples for this library, but here's a nice one.

in this example you can set up an irregularly shaped color swatch.  there are both direct positional points, and points whose x or y will affect a variable somehow.  the way it's supposed to work is, right mouse button re-loads the image.  you have to make a change to the layout image, then save the image between each click.  left clicking a square of course picks that color (actually it prints a message, but use your imagination)

types of changes: except for the first one, the peach colored flags are supposed to be moved in the left-right direction.  the mostly pink flags in the center can be moved together or separately to position each row or the entire graphic.  try moving the two green flags over to the dimmed out suggested location and you should see the swatches spin when you reactivate the layout.

the grey text and lines in the layout don't affect anything at all, just like code comments, so you can feel free to mess them up or delete them completely.  to clarify, the dimmed out flags on their own aren't ever read either, because they aren't black colored as all the valid flags must be.

the program uses this layout file.

example - swatch
Code: [Select]
'$INCLUDE:'calmcompinit.bas'

bgscr& = _NEWIMAGE(800, 600, 32)

SCREEN bgscr&

CONST pi = 3.1415
sqrsiz = 8
flagaltdisplay = 0 ' 0 normal or: -1 to show effect of rotations on parabola
flagfirstpset = -1

DIM ParamsAr(12, 3) AS LONG
DIM Parab01Pt(79, 3) AS LONG, Parab02Pt(79, 3) AS LONG, Parab03Pt(79, 3) AS LONG, Parab04Pt(79, 3) AS LONG ' not really CALM variables, but made 2 dimensioned to use the rotateset functionality
DIM Parab01supp(79) AS SINGLE, Parab02supp(79) AS SINGLE, Parab03supp(79) AS SINGLE, Parab04supp(79) AS SINGLE

GOSUB dimshapes
pfile$ = "ex2param.png" 'used again later
ReadLayout ParamsAr(), pfile$, 0

DO: DO WHILE _MOUSEINPUT: LOOP
 plmb = lmb: lmb = _MOUSEBUTTON(1)
 prmb = rmb: rmb = _MOUSEBUTTON(2)
 cx = _MOUSEX: cy = _MOUSEY

estd = 0 '*

IF (plmb IMP lmb) = 0 THEN
 GOSUB checkemall
END IF

IF (prmb IMP rmb) = 0 OR flagfirstpset THEN
 flagfirstpset = 0
 ReadLayout ParamsAr(), pfile$, 0
 CLS: LOCATE 1, 1: PRINT "right-click to reload layout"

 lastpt = 35
 FOR i = 0 TO lastpt

   IF i < 4 THEN '    < lastpt THEN          < 4 THEN
      pary = i * ParamsAr(2, 0) / 6

   ELSE
      tmppary = i * ParamsAr(2, 0) / 6
      tmpparx = 1 / ParamsAr(5, 0) * prevy ^ 2 + prevy * ParamsAr(3, 0) * (1 / ParamsAr(4, 0))
      parx = 1 / ParamsAr(5, 0) * tmppary ^ 2 + tmppary * ParamsAr(3, 0) * (1 / ParamsAr(4, 0))
      IF estd = 0 THEN
       'decide to use a constant distance when taking a step
       estd = SQR((parx - tmpparx) ^ 2 + (tmppary - prevy) ^ 2)
       pary = i * ParamsAr(2, 0) / 6
      ELSE
         pary = prevy + (tmppary - prevy) * estd / SQR((parx - tmpparx) ^ 2 + (tmppary - prevy) ^ 2)
      END IF

   END IF
   prevy = pary

  'define offsets for each curve
  hoffs(1) = ParamsAr(1, 0) - ParamsAr(0, 1) * 3: voffs(1) = ParamsAr(1, 1)
  hoffs(2) = ParamsAr(6, 0) - ParamsAr(0, 1) * 3: voffs(2) = ParamsAr(6, 1)
  hoffs(3) = ParamsAr(7, 0) - ParamsAr(0, 1) * 3: voffs(3) = ParamsAr(7, 1)
  hoffs(4) = ParamsAr(8, 0) - ParamsAr(0, 1) * 3: voffs(4) = ParamsAr(8, 1)

  'where the magic of geometry happens
  parx = 1 / ParamsAr(5, 0) * pary ^ 2 + pary * ParamsAr(3, 0) * (1 / ParamsAr(4, 0))

  'slopes formula (won't really use it
  cinvslope = 2 / ParamsAr(5, 0) * pary + ParamsAr(3, 0) * (1 / ParamsAr(4, 0))

   Parab01Pt(i, 0) = parx: Parab01Pt(i, 1) = pary
   Parab02Pt(i, 0) = parx: Parab02Pt(i, 1) = pary
   Parab03Pt(i, 0) = parx: Parab03Pt(i, 1) = pary
   Parab04Pt(i, 0) = parx: Parab04Pt(i, 1) = pary

 usingboxesct = 15 'temp var
 'samp line parx + hoffs(1), pary + voffs(1) to (ParamsAr(9, 0)+ i *(ParamsAr(10, 0)-ParamsAr(9, 0))/usingboxesct  , (ParamsAr(9, 1)+  i *((ParamsAr(10, 1)-(ParamsAr(9, 1))/usingboxesct
   orthterm# = ParamsAr(9, 0) + i * (ParamsAr(10, 0) - ParamsAr(9, 0)) / usingboxesct - parx - hoffs(1): IF orthterm# = 0 THEN orthterm# = .0001
   Parab01supp(i) = ATN((ParamsAr(9, 1) + i * (ParamsAr(10, 1) - ParamsAr(9, 1)) / usingboxesct - pary - voffs(1)) / orthterm#)
   orthterm# = ParamsAr(9, 0) + i * (ParamsAr(10, 0) - ParamsAr(9, 0)) / usingboxesct - parx - hoffs(2): IF orthterm# = 0 THEN orthterm# = .0001
   Parab02supp(i) = ATN((ParamsAr(9, 1) + i * (ParamsAr(10, 1) - ParamsAr(9, 1)) / usingboxesct - pary - voffs(2)) / orthterm#)
   orthterm# = ParamsAr(9, 0) + i * (ParamsAr(10, 0) - ParamsAr(9, 0)) / usingboxesct - parx - hoffs(3): IF orthterm# = 0 THEN orthterm# = .0001
   Parab03supp(i) = ATN((ParamsAr(9, 1) + i * (ParamsAr(10, 1) - ParamsAr(9, 1)) / usingboxesct - pary - voffs(3)) / orthterm#)
   orthterm# = ParamsAr(9, 0) + i * (ParamsAr(10, 0) - ParamsAr(9, 0)) / usingboxesct - parx - hoffs(4): IF orthterm# = 0 THEN orthterm# = .0001
   Parab04supp(i) = ATN((ParamsAr(9, 1) + i * (ParamsAr(10, 1) - ParamsAr(9, 1)) / usingboxesct - pary - voffs(4)) / orthterm#)

   IF flagaltdisplay THEN PSET (ParamsAr(1, 0) - ParamsAr(0, 1) * 3 + parx, ParamsAr(1, 1) + pary), _RGB(128, 0, 255)
 NEXT i

   'perform rotations on parabola points (but using axes that the parabola was sitting on)
   rotateset Parab01Pt(), 0, 15, 0, 0, -20
   rotateset Parab02Pt(), 0, 15, -5, 0, -20
   rotateset Parab03Pt(), 0, 15, -10, 0, -20
   rotateset Parab04Pt(), 0, 15, -15, 0, -20

   'add offset amounts to each parabola
   FOR i = 0 TO lastpt
     Parab01Pt(i, 0) = Parab01Pt(i, 0) + hoffs(1): Parab01Pt(i, 1) = Parab01Pt(i, 1) + voffs(1)
     Parab02Pt(i, 0) = Parab02Pt(i, 0) + hoffs(2): Parab02Pt(i, 1) = Parab02Pt(i, 1) + voffs(2)
     Parab03Pt(i, 0) = Parab03Pt(i, 0) + hoffs(3): Parab03Pt(i, 1) = Parab03Pt(i, 1) + voffs(3)
     Parab04Pt(i, 0) = Parab04Pt(i, 0) + hoffs(4): Parab04Pt(i, 1) = Parab04Pt(i, 1) + voffs(4)
   NEXT i

IF flagaltdisplay THEN
 FOR i = 0 TO 15
   PSET (Parab01Pt(i, 0), Parab01Pt(i, 1))
   PSET (Parab02Pt(i, 0), Parab02Pt(i, 1))
   PSET (Parab03Pt(i, 0), Parab03Pt(i, 1))
   PSET (Parab04Pt(i, 0), Parab04Pt(i, 1))
 NEXT i
ELSE
   GOSUB generatepoints
   GOSUB generatemasks
   GOSUB showemall

END IF

END IF

LOOP UNTIL INKEY$ = CHR$(27)


END

' *&&&&&&&&&&&&&*  Mighty subs section *&&&&&&&&&&&&&*

dimshapes:
DIM _pick_01_01(3, 3) AS LONG
DIM LD_pick_01_01(4, 3) AS SINGLE
DIM _pick_01_02(3, 3) AS LONG
DIM LD_pick_01_02(4, 3) AS SINGLE
DIM _pick_01_03(3, 3) AS LONG
DIM LD_pick_01_03(4, 3) AS SINGLE
DIM _pick_01_04(3, 3) AS LONG
DIM LD_pick_01_04(4, 3) AS SINGLE
DIM _pick_01_05(3, 3) AS LONG
DIM LD_pick_01_05(4, 3) AS SINGLE
DIM _pick_01_06(3, 3) AS LONG
DIM LD_pick_01_06(4, 3) AS SINGLE
DIM _pick_01_07(3, 3) AS LONG
DIM LD_pick_01_07(4, 3) AS SINGLE
DIM _pick_01_08(3, 3) AS LONG
DIM LD_pick_01_08(4, 3) AS SINGLE
DIM _pick_01_09(3, 3) AS LONG
DIM LD_pick_01_09(4, 3) AS SINGLE
DIM _pick_01_10(3, 3) AS LONG
DIM LD_pick_01_10(4, 3) AS SINGLE
DIM _pick_01_11(3, 3) AS LONG
DIM LD_pick_01_11(4, 3) AS SINGLE
DIM _pick_01_12(3, 3) AS LONG
DIM LD_pick_01_12(4, 3) AS SINGLE
DIM _pick_01_13(3, 3) AS LONG
DIM LD_pick_01_13(4, 3) AS SINGLE
DIM _pick_01_14(3, 3) AS LONG
DIM LD_pick_01_14(4, 3) AS SINGLE
DIM _pick_01_15(3, 3) AS LONG
DIM LD_pick_01_15(4, 3) AS SINGLE
DIM _pick_01_16(3, 3) AS LONG
DIM LD_pick_01_16(4, 3) AS SINGLE
DIM _pick_02_01(3, 3) AS LONG
DIM LD_pick_02_01(4, 3) AS SINGLE
DIM _pick_02_02(3, 3) AS LONG
DIM LD_pick_02_02(4, 3) AS SINGLE
DIM _pick_02_03(3, 3) AS LONG
DIM LD_pick_02_03(4, 3) AS SINGLE
DIM _pick_02_04(3, 3) AS LONG
DIM LD_pick_02_04(4, 3) AS SINGLE
DIM _pick_02_05(3, 3) AS LONG
DIM LD_pick_02_05(4, 3) AS SINGLE
DIM _pick_02_06(3, 3) AS LONG
DIM LD_pick_02_06(4, 3) AS SINGLE
DIM _pick_02_07(3, 3) AS LONG
DIM LD_pick_02_07(4, 3) AS SINGLE
DIM _pick_02_08(3, 3) AS LONG
DIM LD_pick_02_08(4, 3) AS SINGLE
DIM _pick_02_09(3, 3) AS LONG
DIM LD_pick_02_09(4, 3) AS SINGLE
DIM _pick_02_10(3, 3) AS LONG
DIM LD_pick_02_10(4, 3) AS SINGLE
DIM _pick_02_11(3, 3) AS LONG
DIM LD_pick_02_11(4, 3) AS SINGLE
DIM _pick_02_12(3, 3) AS LONG
DIM LD_pick_02_12(4, 3) AS SINGLE
DIM _pick_02_13(3, 3) AS LONG
DIM LD_pick_02_13(4, 3) AS SINGLE
DIM _pick_02_14(3, 3) AS LONG
DIM LD_pick_02_14(4, 3) AS SINGLE
DIM _pick_02_15(3, 3) AS LONG
DIM LD_pick_02_15(4, 3) AS SINGLE
DIM _pick_02_16(3, 3) AS LONG
DIM LD_pick_02_16(4, 3) AS SINGLE
DIM _pick_03_01(3, 3) AS LONG
DIM LD_pick_03_01(4, 3) AS SINGLE
DIM _pick_03_02(3, 3) AS LONG
DIM LD_pick_03_02(4, 3) AS SINGLE
DIM _pick_03_03(3, 3) AS LONG
DIM LD_pick_03_03(4, 3) AS SINGLE
DIM _pick_03_04(3, 3) AS LONG
DIM LD_pick_03_04(4, 3) AS SINGLE
DIM _pick_03_05(3, 3) AS LONG
DIM LD_pick_03_05(4, 3) AS SINGLE
DIM _pick_03_06(3, 3) AS LONG
DIM LD_pick_03_06(4, 3) AS SINGLE
DIM _pick_03_07(3, 3) AS LONG
DIM LD_pick_03_07(4, 3) AS SINGLE
DIM _pick_03_08(3, 3) AS LONG
DIM LD_pick_03_08(4, 3) AS SINGLE
DIM _pick_03_09(3, 3) AS LONG
DIM LD_pick_03_09(4, 3) AS SINGLE
DIM _pick_03_10(3, 3) AS LONG
DIM LD_pick_03_10(4, 3) AS SINGLE
DIM _pick_03_11(3, 3) AS LONG
DIM LD_pick_03_11(4, 3) AS SINGLE
DIM _pick_03_12(3, 3) AS LONG
DIM LD_pick_03_12(4, 3) AS SINGLE
DIM _pick_03_13(3, 3) AS LONG
DIM LD_pick_03_13(4, 3) AS SINGLE
DIM _pick_03_14(3, 3) AS LONG
DIM LD_pick_03_14(4, 3) AS SINGLE
DIM _pick_03_15(3, 3) AS LONG
DIM LD_pick_03_15(4, 3) AS SINGLE
DIM _pick_03_16(3, 3) AS LONG
DIM LD_pick_03_16(4, 3) AS SINGLE
DIM _pick_04_01(3, 3) AS LONG
DIM LD_pick_04_01(4, 3) AS SINGLE
DIM _pick_04_02(3, 3) AS LONG
DIM LD_pick_04_02(4, 3) AS SINGLE
DIM _pick_04_03(3, 3) AS LONG
DIM LD_pick_04_03(4, 3) AS SINGLE
DIM _pick_04_04(3, 3) AS LONG
DIM LD_pick_04_04(4, 3) AS SINGLE
DIM _pick_04_05(3, 3) AS LONG
DIM LD_pick_04_05(4, 3) AS SINGLE
DIM _pick_04_06(3, 3) AS LONG
DIM LD_pick_04_06(4, 3) AS SINGLE
DIM _pick_04_07(3, 3) AS LONG
DIM LD_pick_04_07(4, 3) AS SINGLE
DIM _pick_04_08(3, 3) AS LONG
DIM LD_pick_04_08(4, 3) AS SINGLE
DIM _pick_04_09(3, 3) AS LONG
DIM LD_pick_04_09(4, 3) AS SINGLE
DIM _pick_04_10(3, 3) AS LONG
DIM LD_pick_04_10(4, 3) AS SINGLE
DIM _pick_04_11(3, 3) AS LONG
DIM LD_pick_04_11(4, 3) AS SINGLE
DIM _pick_04_12(3, 3) AS LONG
DIM LD_pick_04_12(4, 3) AS SINGLE
DIM _pick_04_13(3, 3) AS LONG
DIM LD_pick_04_13(4, 3) AS SINGLE
DIM _pick_04_14(3, 3) AS LONG
DIM LD_pick_04_14(4, 3) AS SINGLE
DIM _pick_04_15(3, 3) AS LONG
DIM LD_pick_04_15(4, 3) AS SINGLE
DIM _pick_04_16(3, 3) AS LONG
DIM LD_pick_04_16(4, 3) AS SINGLE
RETURN

generatepoints:
 FOR i = 0 TO 3
   IF i = 0 OR i = 3 THEN gendirecth = -1 ELSE gendirecth = 1
   IF i = 0 OR i = 1 THEN gendirectv = -1 ELSE gendirectv = 1
   _pick_01_01(i, 0) = Parab01Pt(0, 0) + gendirecth * sqrsiz
   _pick_01_01(i, 1) = Parab01Pt(0, 1) + gendirectv * sqrsiz
   _pick_01_02(i, 0) = Parab01Pt(1, 0) + gendirecth * sqrsiz
   _pick_01_02(i, 1) = Parab01Pt(1, 1) + gendirectv * sqrsiz
   _pick_01_03(i, 0) = Parab01Pt(2, 0) + gendirecth * sqrsiz
   _pick_01_03(i, 1) = Parab01Pt(2, 1) + gendirectv * sqrsiz
   _pick_01_04(i, 0) = Parab01Pt(3, 0) + gendirecth * sqrsiz
   _pick_01_04(i, 1) = Parab01Pt(3, 1) + gendirectv * sqrsiz
   _pick_01_05(i, 0) = Parab01Pt(4, 0) + gendirecth * sqrsiz
   _pick_01_05(i, 1) = Parab01Pt(4, 1) + gendirectv * sqrsiz
   _pick_01_06(i, 0) = Parab01Pt(5, 0) + gendirecth * sqrsiz
   _pick_01_06(i, 1) = Parab01Pt(5, 1) + gendirectv * sqrsiz
   _pick_01_07(i, 0) = Parab01Pt(6, 0) + gendirecth * sqrsiz
   _pick_01_07(i, 1) = Parab01Pt(6, 1) + gendirectv * sqrsiz
   _pick_01_08(i, 0) = Parab01Pt(7, 0) + gendirecth * sqrsiz
   _pick_01_08(i, 1) = Parab01Pt(7, 1) + gendirectv * sqrsiz
   _pick_01_09(i, 0) = Parab01Pt(8, 0) + gendirecth * sqrsiz
   _pick_01_09(i, 1) = Parab01Pt(8, 1) + gendirectv * sqrsiz
   _pick_01_10(i, 0) = Parab01Pt(9, 0) + gendirecth * sqrsiz
   _pick_01_10(i, 1) = Parab01Pt(9, 1) + gendirectv * sqrsiz
   _pick_01_11(i, 0) = Parab01Pt(10, 0) + gendirecth * sqrsiz
   _pick_01_11(i, 1) = Parab01Pt(10, 1) + gendirectv * sqrsiz
   _pick_01_12(i, 0) = Parab01Pt(11, 0) + gendirecth * sqrsiz
   _pick_01_12(i, 1) = Parab01Pt(11, 1) + gendirectv * sqrsiz
   _pick_01_13(i, 0) = Parab01Pt(12, 0) + gendirecth * sqrsiz
   _pick_01_13(i, 1) = Parab01Pt(12, 1) + gendirectv * sqrsiz
   _pick_01_14(i, 0) = Parab01Pt(13, 0) + gendirecth * sqrsiz
   _pick_01_14(i, 1) = Parab01Pt(13, 1) + gendirectv * sqrsiz
   _pick_01_15(i, 0) = Parab01Pt(14, 0) + gendirecth * sqrsiz
   _pick_01_15(i, 1) = Parab01Pt(14, 1) + gendirectv * sqrsiz
   _pick_01_16(i, 0) = Parab01Pt(15, 0) + gendirecth * sqrsiz
   _pick_01_16(i, 1) = Parab01Pt(15, 1) + gendirectv * sqrsiz
   _pick_02_01(i, 0) = Parab02Pt(0, 0) + gendirecth * sqrsiz
   _pick_02_01(i, 1) = Parab02Pt(0, 1) + gendirectv * sqrsiz
   _pick_02_02(i, 0) = Parab02Pt(1, 0) + gendirecth * sqrsiz
   _pick_02_02(i, 1) = Parab02Pt(1, 1) + gendirectv * sqrsiz
   _pick_02_03(i, 0) = Parab02Pt(2, 0) + gendirecth * sqrsiz
   _pick_02_03(i, 1) = Parab02Pt(2, 1) + gendirectv * sqrsiz
   _pick_02_04(i, 0) = Parab02Pt(3, 0) + gendirecth * sqrsiz
   _pick_02_04(i, 1) = Parab02Pt(3, 1) + gendirectv * sqrsiz
   _pick_02_05(i, 0) = Parab02Pt(4, 0) + gendirecth * sqrsiz
   _pick_02_05(i, 1) = Parab02Pt(4, 1) + gendirectv * sqrsiz
   _pick_02_06(i, 0) = Parab02Pt(5, 0) + gendirecth * sqrsiz
   _pick_02_06(i, 1) = Parab02Pt(5, 1) + gendirectv * sqrsiz
   _pick_02_07(i, 0) = Parab02Pt(6, 0) + gendirecth * sqrsiz
   _pick_02_07(i, 1) = Parab02Pt(6, 1) + gendirectv * sqrsiz
   _pick_02_08(i, 0) = Parab02Pt(7, 0) + gendirecth * sqrsiz
   _pick_02_08(i, 1) = Parab02Pt(7, 1) + gendirectv * sqrsiz
   _pick_02_09(i, 0) = Parab02Pt(8, 0) + gendirecth * sqrsiz
   _pick_02_09(i, 1) = Parab02Pt(8, 1) + gendirectv * sqrsiz
   _pick_02_10(i, 0) = Parab02Pt(9, 0) + gendirecth * sqrsiz
   _pick_02_10(i, 1) = Parab02Pt(9, 1) + gendirectv * sqrsiz
   _pick_02_11(i, 0) = Parab02Pt(10, 0) + gendirecth * sqrsiz
   _pick_02_11(i, 1) = Parab02Pt(10, 1) + gendirectv * sqrsiz
   _pick_02_12(i, 0) = Parab02Pt(11, 0) + gendirecth * sqrsiz
   _pick_02_12(i, 1) = Parab02Pt(11, 1) + gendirectv * sqrsiz
   _pick_02_13(i, 0) = Parab02Pt(12, 0) + gendirecth * sqrsiz
   _pick_02_13(i, 1) = Parab02Pt(12, 1) + gendirectv * sqrsiz
   _pick_02_14(i, 0) = Parab02Pt(13, 0) + gendirecth * sqrsiz
   _pick_02_14(i, 1) = Parab02Pt(13, 1) + gendirectv * sqrsiz
   _pick_02_15(i, 0) = Parab02Pt(14, 0) + gendirecth * sqrsiz
   _pick_02_15(i, 1) = Parab02Pt(14, 1) + gendirectv * sqrsiz
   _pick_02_16(i, 0) = Parab02Pt(15, 0) + gendirecth * sqrsiz
   _pick_02_16(i, 1) = Parab02Pt(15, 1) + gendirectv * sqrsiz
   _pick_03_01(i, 0) = Parab03Pt(0, 0) + gendirecth * sqrsiz
   _pick_03_01(i, 1) = Parab03Pt(0, 1) + gendirectv * sqrsiz
   _pick_03_02(i, 0) = Parab03Pt(1, 0) + gendirecth * sqrsiz
   _pick_03_02(i, 1) = Parab03Pt(1, 1) + gendirectv * sqrsiz
   _pick_03_03(i, 0) = Parab03Pt(2, 0) + gendirecth * sqrsiz
   _pick_03_03(i, 1) = Parab03Pt(2, 1) + gendirectv * sqrsiz
   _pick_03_04(i, 0) = Parab03Pt(3, 0) + gendirecth * sqrsiz
   _pick_03_04(i, 1) = Parab03Pt(3, 1) + gendirectv * sqrsiz
   _pick_03_05(i, 0) = Parab03Pt(4, 0) + gendirecth * sqrsiz
   _pick_03_05(i, 1) = Parab03Pt(4, 1) + gendirectv * sqrsiz
   _pick_03_06(i, 0) = Parab03Pt(5, 0) + gendirecth * sqrsiz
   _pick_03_06(i, 1) = Parab03Pt(5, 1) + gendirectv * sqrsiz
   _pick_03_07(i, 0) = Parab03Pt(6, 0) + gendirecth * sqrsiz
   _pick_03_07(i, 1) = Parab03Pt(6, 1) + gendirectv * sqrsiz
   _pick_03_08(i, 0) = Parab03Pt(7, 0) + gendirecth * sqrsiz
   _pick_03_08(i, 1) = Parab03Pt(7, 1) + gendirectv * sqrsiz
   _pick_03_09(i, 0) = Parab03Pt(8, 0) + gendirecth * sqrsiz
   _pick_03_09(i, 1) = Parab03Pt(8, 1) + gendirectv * sqrsiz
   _pick_03_10(i, 0) = Parab03Pt(9, 0) + gendirecth * sqrsiz
   _pick_03_10(i, 1) = Parab03Pt(9, 1) + gendirectv * sqrsiz
   _pick_03_11(i, 0) = Parab03Pt(10, 0) + gendirecth * sqrsiz
   _pick_03_11(i, 1) = Parab03Pt(10, 1) + gendirectv * sqrsiz
   _pick_03_12(i, 0) = Parab03Pt(11, 0) + gendirecth * sqrsiz
   _pick_03_12(i, 1) = Parab03Pt(11, 1) + gendirectv * sqrsiz
   _pick_03_13(i, 0) = Parab03Pt(12, 0) + gendirecth * sqrsiz
   _pick_03_13(i, 1) = Parab03Pt(12, 1) + gendirectv * sqrsiz
   _pick_03_14(i, 0) = Parab03Pt(13, 0) + gendirecth * sqrsiz
   _pick_03_14(i, 1) = Parab03Pt(13, 1) + gendirectv * sqrsiz
   _pick_03_15(i, 0) = Parab03Pt(14, 0) + gendirecth * sqrsiz
   _pick_03_15(i, 1) = Parab03Pt(14, 1) + gendirectv * sqrsiz
   _pick_03_16(i, 0) = Parab03Pt(15, 0) + gendirecth * sqrsiz
   _pick_03_16(i, 1) = Parab03Pt(15, 1) + gendirectv * sqrsiz
   _pick_04_01(i, 0) = Parab04Pt(0, 0) + gendirecth * sqrsiz
   _pick_04_01(i, 1) = Parab04Pt(0, 1) + gendirectv * sqrsiz
   _pick_04_02(i, 0) = Parab04Pt(1, 0) + gendirecth * sqrsiz
   _pick_04_02(i, 1) = Parab04Pt(1, 1) + gendirectv * sqrsiz
   _pick_04_03(i, 0) = Parab04Pt(2, 0) + gendirecth * sqrsiz
   _pick_04_03(i, 1) = Parab04Pt(2, 1) + gendirectv * sqrsiz
   _pick_04_04(i, 0) = Parab04Pt(3, 0) + gendirecth * sqrsiz
   _pick_04_04(i, 1) = Parab04Pt(3, 1) + gendirectv * sqrsiz
   _pick_04_05(i, 0) = Parab04Pt(4, 0) + gendirecth * sqrsiz
   _pick_04_05(i, 1) = Parab04Pt(4, 1) + gendirectv * sqrsiz
   _pick_04_06(i, 0) = Parab04Pt(5, 0) + gendirecth * sqrsiz
   _pick_04_06(i, 1) = Parab04Pt(5, 1) + gendirectv * sqrsiz
   _pick_04_07(i, 0) = Parab04Pt(6, 0) + gendirecth * sqrsiz
   _pick_04_07(i, 1) = Parab04Pt(6, 1) + gendirectv * sqrsiz
   _pick_04_08(i, 0) = Parab04Pt(7, 0) + gendirecth * sqrsiz
   _pick_04_08(i, 1) = Parab04Pt(7, 1) + gendirectv * sqrsiz
   _pick_04_09(i, 0) = Parab04Pt(8, 0) + gendirecth * sqrsiz
   _pick_04_09(i, 1) = Parab04Pt(8, 1) + gendirectv * sqrsiz
   _pick_04_10(i, 0) = Parab04Pt(9, 0) + gendirecth * sqrsiz
   _pick_04_10(i, 1) = Parab04Pt(9, 1) + gendirectv * sqrsiz
   _pick_04_11(i, 0) = Parab04Pt(10, 0) + gendirecth * sqrsiz
   _pick_04_11(i, 1) = Parab04Pt(10, 1) + gendirectv * sqrsiz
   _pick_04_12(i, 0) = Parab04Pt(11, 0) + gendirecth * sqrsiz
   _pick_04_12(i, 1) = Parab04Pt(11, 1) + gendirectv * sqrsiz
   _pick_04_13(i, 0) = Parab04Pt(12, 0) + gendirecth * sqrsiz
   _pick_04_13(i, 1) = Parab04Pt(12, 1) + gendirectv * sqrsiz
   _pick_04_14(i, 0) = Parab04Pt(13, 0) + gendirecth * sqrsiz
   _pick_04_14(i, 1) = Parab04Pt(13, 1) + gendirectv * sqrsiz
   _pick_04_15(i, 0) = Parab04Pt(14, 0) + gendirecth * sqrsiz
   _pick_04_15(i, 1) = Parab04Pt(14, 1) + gendirectv * sqrsiz
   _pick_04_16(i, 0) = Parab04Pt(15, 0) + gendirecth * sqrsiz
   _pick_04_16(i, 1) = Parab04Pt(15, 1) + gendirectv * sqrsiz

 NEXT i

' and rotate each square
 rotateset _pick_01_01(), 0, 3, Parab01Pt(0, 0), Parab01Pt(0, 1), (Parab01supp(0) * 180 / pi)
 rotateset _pick_01_02(), 0, 3, Parab01Pt(1, 0), Parab01Pt(1, 1), (Parab01supp(1) * 180 / pi)
 rotateset _pick_01_03(), 0, 3, Parab01Pt(2, 0), Parab01Pt(2, 1), (Parab01supp(2) * 180 / pi)
 rotateset _pick_01_04(), 0, 3, Parab01Pt(3, 0), Parab01Pt(3, 1), (Parab01supp(3) * 180 / pi)
 rotateset _pick_01_05(), 0, 3, Parab01Pt(4, 0), Parab01Pt(4, 1), (Parab01supp(4) * 180 / pi)
 rotateset _pick_01_06(), 0, 3, Parab01Pt(5, 0), Parab01Pt(5, 1), (Parab01supp(5) * 180 / pi)
 rotateset _pick_01_07(), 0, 3, Parab01Pt(6, 0), Parab01Pt(6, 1), (Parab01supp(6) * 180 / pi)
 rotateset _pick_01_08(), 0, 3, Parab01Pt(7, 0), Parab01Pt(7, 1), (Parab01supp(7) * 180 / pi)
 rotateset _pick_01_09(), 0, 3, Parab01Pt(8, 0), Parab01Pt(8, 1), (Parab01supp(8) * 180 / pi)
 rotateset _pick_01_10(), 0, 3, Parab01Pt(9, 0), Parab01Pt(9, 1), (Parab01supp(9) * 180 / pi)
 rotateset _pick_01_11(), 0, 3, Parab01Pt(10, 0), Parab01Pt(10, 1), (Parab01supp(10) * 180 / pi)
 rotateset _pick_01_12(), 0, 3, Parab01Pt(11, 0), Parab01Pt(11, 1), (Parab01supp(11) * 180 / pi)
 rotateset _pick_01_13(), 0, 3, Parab01Pt(12, 0), Parab01Pt(12, 1), (Parab01supp(12) * 180 / pi)
 rotateset _pick_01_14(), 0, 3, Parab01Pt(13, 0), Parab01Pt(13, 1), (Parab01supp(13) * 180 / pi)
 rotateset _pick_01_15(), 0, 3, Parab01Pt(14, 0), Parab01Pt(14, 1), (Parab01supp(14) * 180 / pi)
 rotateset _pick_01_16(), 0, 3, Parab01Pt(15, 0), Parab01Pt(15, 1), (Parab01supp(15) * 180 / pi)
 rotateset _pick_02_01(), 0, 3, Parab02Pt(0, 0), Parab02Pt(0, 1), (Parab02supp(0) * 180 / pi)
 rotateset _pick_02_02(), 0, 3, Parab02Pt(1, 0), Parab02Pt(1, 1), (Parab02supp(1) * 180 / pi)
 rotateset _pick_02_03(), 0, 3, Parab02Pt(2, 0), Parab02Pt(2, 1), (Parab02supp(2) * 180 / pi)
 rotateset _pick_02_04(), 0, 3, Parab02Pt(3, 0), Parab02Pt(3, 1), (Parab02supp(3) * 180 / pi)
 rotateset _pick_02_05(), 0, 3, Parab02Pt(4, 0), Parab02Pt(4, 1), (Parab02supp(4) * 180 / pi)
 rotateset _pick_02_06(), 0, 3, Parab02Pt(5, 0), Parab02Pt(5, 1), (Parab02supp(5) * 180 / pi)
 rotateset _pick_02_07(), 0, 3, Parab02Pt(6, 0), Parab02Pt(6, 1), (Parab02supp(6) * 180 / pi)
 rotateset _pick_02_08(), 0, 3, Parab02Pt(7, 0), Parab02Pt(7, 1), (Parab02supp(7) * 180 / pi)
 rotateset _pick_02_09(), 0, 3, Parab02Pt(8, 0), Parab02Pt(8, 1), (Parab02supp(8) * 180 / pi)
 rotateset _pick_02_10(), 0, 3, Parab02Pt(9, 0), Parab02Pt(9, 1), (Parab02supp(9) * 180 / pi)
 rotateset _pick_02_11(), 0, 3, Parab02Pt(10, 0), Parab02Pt(10, 1), (Parab02supp(10) * 180 / pi)
 rotateset _pick_02_12(), 0, 3, Parab02Pt(11, 0), Parab02Pt(11, 1), (Parab02supp(11) * 180 / pi)
 rotateset _pick_02_13(), 0, 3, Parab02Pt(12, 0), Parab02Pt(12, 1), (Parab02supp(12) * 180 / pi)
 rotateset _pick_02_14(), 0, 3, Parab02Pt(13, 0), Parab02Pt(13, 1), (Parab02supp(13) * 180 / pi)
 rotateset _pick_02_15(), 0, 3, Parab02Pt(14, 0), Parab02Pt(14, 1), (Parab02supp(14) * 180 / pi)
 rotateset _pick_02_16(), 0, 3, Parab02Pt(15, 0), Parab02Pt(15, 1), (Parab02supp(15) * 180 / pi)
 rotateset _pick_03_01(), 0, 3, Parab03Pt(0, 0), Parab03Pt(0, 1), (Parab03supp(0) * 180 / pi)
 rotateset _pick_03_02(), 0, 3, Parab03Pt(1, 0), Parab03Pt(1, 1), (Parab03supp(1) * 180 / pi)
 rotateset _pick_03_03(), 0, 3, Parab03Pt(2, 0), Parab03Pt(2, 1), (Parab03supp(2) * 180 / pi)
 rotateset _pick_03_04(), 0, 3, Parab03Pt(3, 0), Parab03Pt(3, 1), (Parab03supp(3) * 180 / pi)
 rotateset _pick_03_05(), 0, 3, Parab03Pt(4, 0), Parab03Pt(4, 1), (Parab03supp(4) * 180 / pi)
 rotateset _pick_03_06(), 0, 3, Parab03Pt(5, 0), Parab03Pt(5, 1), (Parab03supp(5) * 180 / pi)
 rotateset _pick_03_07(), 0, 3, Parab03Pt(6, 0), Parab03Pt(6, 1), (Parab03supp(6) * 180 / pi)
 rotateset _pick_03_08(), 0, 3, Parab03Pt(7, 0), Parab03Pt(7, 1), (Parab03supp(7) * 180 / pi)
 rotateset _pick_03_09(), 0, 3, Parab03Pt(8, 0), Parab03Pt(8, 1), (Parab03supp(8) * 180 / pi)
 rotateset _pick_03_10(), 0, 3, Parab03Pt(9, 0), Parab03Pt(9, 1), (Parab03supp(9) * 180 / pi)
 rotateset _pick_03_11(), 0, 3, Parab03Pt(10, 0), Parab03Pt(10, 1), (Parab03supp(10) * 180 / pi)
 rotateset _pick_03_12(), 0, 3, Parab03Pt(11, 0), Parab03Pt(11, 1), (Parab03supp(11) * 180 / pi)
 rotateset _pick_03_13(), 0, 3, Parab03Pt(12, 0), Parab03Pt(12, 1), (Parab03supp(12) * 180 / pi)
 rotateset _pick_03_14(), 0, 3, Parab03Pt(13, 0), Parab03Pt(13, 1), (Parab03supp(13) * 180 / pi)
 rotateset _pick_03_15(), 0, 3, Parab03Pt(14, 0), Parab03Pt(14, 1), (Parab03supp(14) * 180 / pi)
 rotateset _pick_03_16(), 0, 3, Parab03Pt(15, 0), Parab03Pt(15, 1), (Parab03supp(15) * 180 / pi)
 rotateset _pick_04_01(), 0, 3, Parab04Pt(0, 0), Parab04Pt(0, 1), (Parab04supp(0) * 180 / pi)
 rotateset _pick_04_02(), 0, 3, Parab04Pt(1, 0), Parab04Pt(1, 1), (Parab04supp(1) * 180 / pi)
 rotateset _pick_04_03(), 0, 3, Parab04Pt(2, 0), Parab04Pt(2, 1), (Parab04supp(2) * 180 / pi)
 rotateset _pick_04_04(), 0, 3, Parab04Pt(3, 0), Parab04Pt(3, 1), (Parab04supp(3) * 180 / pi)
 rotateset _pick_04_05(), 0, 3, Parab04Pt(4, 0), Parab04Pt(4, 1), (Parab04supp(4) * 180 / pi)
 rotateset _pick_04_06(), 0, 3, Parab04Pt(5, 0), Parab04Pt(5, 1), (Parab04supp(5) * 180 / pi)
 rotateset _pick_04_07(), 0, 3, Parab04Pt(6, 0), Parab04Pt(6, 1), (Parab04supp(6) * 180 / pi)
 rotateset _pick_04_08(), 0, 3, Parab04Pt(7, 0), Parab04Pt(7, 1), (Parab04supp(7) * 180 / pi)
 rotateset _pick_04_09(), 0, 3, Parab04Pt(8, 0), Parab04Pt(8, 1), (Parab04supp(8) * 180 / pi)
 rotateset _pick_04_10(), 0, 3, Parab04Pt(9, 0), Parab04Pt(9, 1), (Parab04supp(9) * 180 / pi)
 rotateset _pick_04_11(), 0, 3, Parab04Pt(10, 0), Parab04Pt(10, 1), (Parab04supp(10) * 180 / pi)
 rotateset _pick_04_12(), 0, 3, Parab04Pt(11, 0), Parab04Pt(11, 1), (Parab04supp(11) * 180 / pi)
 rotateset _pick_04_13(), 0, 3, Parab04Pt(12, 0), Parab04Pt(12, 1), (Parab04supp(12) * 180 / pi)
 rotateset _pick_04_14(), 0, 3, Parab04Pt(13, 0), Parab04Pt(13, 1), (Parab04supp(13) * 180 / pi)
 rotateset _pick_04_15(), 0, 3, Parab04Pt(14, 0), Parab04Pt(14, 1), (Parab04supp(14) * 180 / pi)
 rotateset _pick_04_16(), 0, 3, Parab04Pt(15, 0), Parab04Pt(15, 1), (Parab04supp(15) * 180 / pi)

RETURN


generatemasks:

PDLineUpPoints _pick_01_01(), LD_pick_01_01()
GenerateShapeMask 0, _pick_01_01(), LD_pick_01_01(), 0, 0
PDLineUpPoints _pick_01_02(), LD_pick_01_02()
GenerateShapeMask 0, _pick_01_02(), LD_pick_01_02(), 0, 0
PDLineUpPoints _pick_01_03(), LD_pick_01_03()
GenerateShapeMask 0, _pick_01_03(), LD_pick_01_03(), 0, 0
PDLineUpPoints _pick_01_04(), LD_pick_01_04()
GenerateShapeMask 0, _pick_01_04(), LD_pick_01_04(), 0, 0
PDLineUpPoints _pick_01_05(), LD_pick_01_05()
GenerateShapeMask 0, _pick_01_05(), LD_pick_01_05(), 0, 0
PDLineUpPoints _pick_01_06(), LD_pick_01_06()
GenerateShapeMask 0, _pick_01_06(), LD_pick_01_06(), 0, 0
PDLineUpPoints _pick_01_07(), LD_pick_01_07()
GenerateShapeMask 0, _pick_01_07(), LD_pick_01_07(), 0, 0
PDLineUpPoints _pick_01_08(), LD_pick_01_08()
GenerateShapeMask 0, _pick_01_08(), LD_pick_01_08(), 0, 0
PDLineUpPoints _pick_01_09(), LD_pick_01_09()
GenerateShapeMask 0, _pick_01_09(), LD_pick_01_09(), 0, 0
PDLineUpPoints _pick_01_10(), LD_pick_01_10()
GenerateShapeMask 0, _pick_01_10(), LD_pick_01_10(), 0, 0
PDLineUpPoints _pick_01_11(), LD_pick_01_11()
GenerateShapeMask 0, _pick_01_11(), LD_pick_01_11(), 0, 0
PDLineUpPoints _pick_01_12(), LD_pick_01_12()
GenerateShapeMask 0, _pick_01_12(), LD_pick_01_12(), 0, 0
PDLineUpPoints _pick_01_13(), LD_pick_01_13()
GenerateShapeMask 0, _pick_01_13(), LD_pick_01_13(), 0, 0
PDLineUpPoints _pick_01_14(), LD_pick_01_14()
GenerateShapeMask 0, _pick_01_14(), LD_pick_01_14(), 0, 0
PDLineUpPoints _pick_01_15(), LD_pick_01_15()
GenerateShapeMask 0, _pick_01_15(), LD_pick_01_15(), 0, 0
PDLineUpPoints _pick_01_16(), LD_pick_01_16()
GenerateShapeMask 0, _pick_01_16(), LD_pick_01_16(), 0, 0
PDLineUpPoints _pick_02_01(), LD_pick_02_01()
GenerateShapeMask 0, _pick_02_01(), LD_pick_02_01(), 0, 0
PDLineUpPoints _pick_02_02(), LD_pick_02_02()
GenerateShapeMask 0, _pick_02_02(), LD_pick_02_02(), 0, 0
PDLineUpPoints _pick_02_03(), LD_pick_02_03()
GenerateShapeMask 0, _pick_02_03(), LD_pick_02_03(), 0, 0
PDLineUpPoints _pick_02_04(), LD_pick_02_04()
GenerateShapeMask 0, _pick_02_04(), LD_pick_02_04(), 0, 0
PDLineUpPoints _pick_02_05(), LD_pick_02_05()
GenerateShapeMask 0, _pick_02_05(), LD_pick_02_05(), 0, 0
PDLineUpPoints _pick_02_06(), LD_pick_02_06()
GenerateShapeMask 0, _pick_02_06(), LD_pick_02_06(), 0, 0
PDLineUpPoints _pick_02_07(), LD_pick_02_07()
GenerateShapeMask 0, _pick_02_07(), LD_pick_02_07(), 0, 0
PDLineUpPoints _pick_02_08(), LD_pick_02_08()
GenerateShapeMask 0, _pick_02_08(), LD_pick_02_08(), 0, 0
PDLineUpPoints _pick_02_09(), LD_pick_02_09()
GenerateShapeMask 0, _pick_02_09(), LD_pick_02_09(), 0, 0
PDLineUpPoints _pick_02_10(), LD_pick_02_10()
GenerateShapeMask 0, _pick_02_10(), LD_pick_02_10(), 0, 0
PDLineUpPoints _pick_02_11(), LD_pick_02_11()
GenerateShapeMask 0, _pick_02_11(), LD_pick_02_11(), 0, 0
PDLineUpPoints _pick_02_12(), LD_pick_02_12()
GenerateShapeMask 0, _pick_02_12(), LD_pick_02_12(), 0, 0
PDLineUpPoints _pick_02_13(), LD_pick_02_13()
GenerateShapeMask 0, _pick_02_13(), LD_pick_02_13(), 0, 0
PDLineUpPoints _pick_02_14(), LD_pick_02_14()
GenerateShapeMask 0, _pick_02_14(), LD_pick_02_14(), 0, 0
PDLineUpPoints _pick_02_15(), LD_pick_02_15()
GenerateShapeMask 0, _pick_02_15(), LD_pick_02_15(), 0, 0
PDLineUpPoints _pick_02_16(), LD_pick_02_16()
GenerateShapeMask 0, _pick_02_16(), LD_pick_02_16(), 0, 0
PDLineUpPoints _pick_03_01(), LD_pick_03_01()
GenerateShapeMask 0, _pick_03_01(), LD_pick_03_01(), 0, 0
PDLineUpPoints _pick_03_02(), LD_pick_03_02()
GenerateShapeMask 0, _pick_03_02(), LD_pick_03_02(), 0, 0
PDLineUpPoints _pick_03_03(), LD_pick_03_03()
GenerateShapeMask 0, _pick_03_03(), LD_pick_03_03(), 0, 0
PDLineUpPoints _pick_03_04(), LD_pick_03_04()
GenerateShapeMask 0, _pick_03_04(), LD_pick_03_04(), 0, 0
PDLineUpPoints _pick_03_05(), LD_pick_03_05()
GenerateShapeMask 0, _pick_03_05(), LD_pick_03_05(), 0, 0
PDLineUpPoints _pick_03_06(), LD_pick_03_06()
GenerateShapeMask 0, _pick_03_06(), LD_pick_03_06(), 0, 0
PDLineUpPoints _pick_03_07(), LD_pick_03_07()
GenerateShapeMask 0, _pick_03_07(), LD_pick_03_07(), 0, 0
PDLineUpPoints _pick_03_08(), LD_pick_03_08()
GenerateShapeMask 0, _pick_03_08(), LD_pick_03_08(), 0, 0
PDLineUpPoints _pick_03_09(), LD_pick_03_09()
GenerateShapeMask 0, _pick_03_09(), LD_pick_03_09(), 0, 0
PDLineUpPoints _pick_03_10(), LD_pick_03_10()
GenerateShapeMask 0, _pick_03_10(), LD_pick_03_10(), 0, 0
PDLineUpPoints _pick_03_11(), LD_pick_03_11()
GenerateShapeMask 0, _pick_03_11(), LD_pick_03_11(), 0, 0
PDLineUpPoints _pick_03_12(), LD_pick_03_12()
GenerateShapeMask 0, _pick_03_12(), LD_pick_03_12(), 0, 0
PDLineUpPoints _pick_03_13(), LD_pick_03_13()
GenerateShapeMask 0, _pick_03_13(), LD_pick_03_13(), 0, 0
PDLineUpPoints _pick_03_14(), LD_pick_03_14()
GenerateShapeMask 0, _pick_03_14(), LD_pick_03_14(), 0, 0
PDLineUpPoints _pick_03_15(), LD_pick_03_15()
GenerateShapeMask 0, _pick_03_15(), LD_pick_03_15(), 0, 0
PDLineUpPoints _pick_03_16(), LD_pick_03_16()
GenerateShapeMask 0, _pick_03_16(), LD_pick_03_16(), 0, 0
PDLineUpPoints _pick_04_01(), LD_pick_04_01()
GenerateShapeMask 0, _pick_04_01(), LD_pick_04_01(), 0, 0
PDLineUpPoints _pick_04_02(), LD_pick_04_02()
GenerateShapeMask 0, _pick_04_02(), LD_pick_04_02(), 0, 0
PDLineUpPoints _pick_04_03(), LD_pick_04_03()
GenerateShapeMask 0, _pick_04_03(), LD_pick_04_03(), 0, 0
PDLineUpPoints _pick_04_04(), LD_pick_04_04()
GenerateShapeMask 0, _pick_04_04(), LD_pick_04_04(), 0, 0
PDLineUpPoints _pick_04_05(), LD_pick_04_05()
GenerateShapeMask 0, _pick_04_05(), LD_pick_04_05(), 0, 0
PDLineUpPoints _pick_04_06(), LD_pick_04_06()
GenerateShapeMask 0, _pick_04_06(), LD_pick_04_06(), 0, 0
PDLineUpPoints _pick_04_07(), LD_pick_04_07()
GenerateShapeMask 0, _pick_04_07(), LD_pick_04_07(), 0, 0
PDLineUpPoints _pick_04_08(), LD_pick_04_08()
GenerateShapeMask 0, _pick_04_08(), LD_pick_04_08(), 0, 0
PDLineUpPoints _pick_04_09(), LD_pick_04_09()
GenerateShapeMask 0, _pick_04_09(), LD_pick_04_09(), 0, 0
PDLineUpPoints _pick_04_10(), LD_pick_04_10()
GenerateShapeMask 0, _pick_04_10(), LD_pick_04_10(), 0, 0
PDLineUpPoints _pick_04_11(), LD_pick_04_11()
GenerateShapeMask 0, _pick_04_11(), LD_pick_04_11(), 0, 0
PDLineUpPoints _pick_04_12(), LD_pick_04_12()
GenerateShapeMask 0, _pick_04_12(), LD_pick_04_12(), 0, 0
PDLineUpPoints _pick_04_13(), LD_pick_04_13()
GenerateShapeMask 0, _pick_04_13(), LD_pick_04_13(), 0, 0
PDLineUpPoints _pick_04_14(), LD_pick_04_14()
GenerateShapeMask 0, _pick_04_14(), LD_pick_04_14(), 0, 0
PDLineUpPoints _pick_04_15(), LD_pick_04_15()
GenerateShapeMask 0, _pick_04_15(), LD_pick_04_15(), 0, 0
PDLineUpPoints _pick_04_16(), LD_pick_04_16()
GenerateShapeMask 0, _pick_04_16(), LD_pick_04_16(), 0, 0
RETURN

showemall:
fillhue& = _RGB32(25, 30, 25)
FillBunch _pick_01_01(), "", 0, _DEST
fillhue& = _RGB32(30, 45, 30)
FillBunch _pick_01_02(), "", 0, _DEST
fillhue& = _RGB32(30, 60, 30)
FillBunch _pick_01_03(), "", 0, _DEST
fillhue& = _RGB32(30, 75, 30)
FillBunch _pick_01_04(), "", 0, _DEST
fillhue& = _RGB32(30, 90, 30)
FillBunch _pick_01_05(), "", 0, _DEST
fillhue& = _RGB32(30, 105, 30)
FillBunch _pick_01_06(), "", 0, _DEST
fillhue& = _RGB32(30, 120, 30)
FillBunch _pick_01_07(), "", 0, _DEST
fillhue& = _RGB32(30, 135, 30)
FillBunch _pick_01_08(), "", 0, _DEST
fillhue& = _RGB32(30, 150, 30)
FillBunch _pick_01_09(), "", 0, _DEST
fillhue& = _RGB32(30, 165, 30)
FillBunch _pick_01_10(), "", 0, _DEST
fillhue& = _RGB32(30, 180, 30)
FillBunch _pick_01_11(), "", 0, _DEST
fillhue& = _RGB32(30, 195, 30)
FillBunch _pick_01_12(), "", 0, _DEST
fillhue& = _RGB32(30, 210, 30)
FillBunch _pick_01_13(), "", 0, _DEST
fillhue& = _RGB32(30, 225, 30)
FillBunch _pick_01_14(), "", 0, _DEST
fillhue& = _RGB32(30, 240, 30)
FillBunch _pick_01_15(), "", 0, _DEST
fillhue& = _RGB32(30, 255, 30)
FillBunch _pick_01_16(), "", 0, _DEST

fillhue& = _RGB32(25, 25, 30)
FillBunch _pick_02_01(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 45)
FillBunch _pick_02_02(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 60)
FillBunch _pick_02_03(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 75)
FillBunch _pick_02_04(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 90)
FillBunch _pick_02_05(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 105)
FillBunch _pick_02_06(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 120)
FillBunch _pick_02_07(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 135)
FillBunch _pick_02_08(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 150)
FillBunch _pick_02_09(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 165)
FillBunch _pick_02_10(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 180)
FillBunch _pick_02_11(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 195)
FillBunch _pick_02_12(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 210)
FillBunch _pick_02_13(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 225)
FillBunch _pick_02_14(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 240)
FillBunch _pick_02_15(), "", 0, _DEST
fillhue& = _RGB32(30, 30, 255)
FillBunch _pick_02_16(), "", 0, _DEST

fillhue& = _RGB32(30, 25, 25)
FillBunch _pick_03_01(), "", 0, _DEST
fillhue& = _RGB32(45, 30, 30)
FillBunch _pick_03_02(), "", 0, _DEST
fillhue& = _RGB32(60, 30, 30)
FillBunch _pick_03_03(), "", 0, _DEST
fillhue& = _RGB32(75, 30, 30)
FillBunch _pick_03_04(), "", 0, _DEST
fillhue& = _RGB32(90, 30, 30)
FillBunch _pick_03_05(), "", 0, _DEST
fillhue& = _RGB32(105, 30, 30)
FillBunch _pick_03_06(), "", 0, _DEST
fillhue& = _RGB32(120, 30, 30)
FillBunch _pick_03_07(), "", 0, _DEST
fillhue& = _RGB32(135, 30, 30)
FillBunch _pick_03_08(), "", 0, _DEST
fillhue& = _RGB32(150, 30, 30)
FillBunch _pick_03_09(), "", 0, _DEST
fillhue& = _RGB32(165, 30, 30)
FillBunch _pick_03_10(), "", 0, _DEST
fillhue& = _RGB32(180, 30, 30)
FillBunch _pick_03_11(), "", 0, _DEST
fillhue& = _RGB32(195, 30, 30)
FillBunch _pick_03_12(), "", 0, _DEST
fillhue& = _RGB32(210, 30, 30)
FillBunch _pick_03_13(), "", 0, _DEST
fillhue& = _RGB32(225, 30, 30)
FillBunch _pick_03_14(), "", 0, _DEST
fillhue& = _RGB32(240, 30, 30)
FillBunch _pick_03_15(), "", 0, _DEST
fillhue& = _RGB32(255, 30, 30)
FillBunch _pick_03_16(), "", 0, _DEST

fillhue& = _RGB32(30, 30, 30)
FillBunch _pick_04_01(), "", 0, _DEST
fillhue& = _RGB32(40, 50, 60)
FillBunch _pick_04_02(), "", 0, _DEST
fillhue& = _RGB32(50, 80, 80)
FillBunch _pick_04_03(), "", 0, _DEST
fillhue& = _RGB32(70, 110, 90)
FillBunch _pick_04_04(), "", 0, _DEST
fillhue& = _RGB32(100, 130, 100)
FillBunch _pick_04_05(), "", 0, _DEST
fillhue& = _RGB32(130, 140, 120)
FillBunch _pick_04_06(), "", 0, _DEST
fillhue& = _RGB32(150, 150, 150)
FillBunch _pick_04_07(), "", 0, _DEST
fillhue& = _RGB32(160, 170, 180)
FillBunch _pick_04_08(), "", 0, _DEST
fillhue& = _RGB32(170, 200, 200)
FillBunch _pick_04_09(), "", 0, _DEST
fillhue& = _RGB32(190, 230, 210)
FillBunch _pick_04_10(), "", 0, _DEST
fillhue& = _RGB32(205, 240, 215)
FillBunch _pick_04_11(), "", 0, _DEST
fillhue& = _RGB32(215, 245, 225)
FillBunch _pick_04_12(), "", 0, _DEST
fillhue& = _RGB32(230, 245, 230)
FillBunch _pick_04_13(), "", 0, _DEST
fillhue& = _RGB32(235, 250, 235)
FillBunch _pick_04_14(), "", 0, _DEST
fillhue& = _RGB32(240, 255, 245)
FillBunch _pick_04_15(), "", 0, _DEST
fillhue& = _RGB32(245, 255, 250)
FillBunch _pick_04_16(), "", 0, _DEST
RETURN

checkemall:
IF PDPointCheck(cx, cy, LD_pick_01_01()) THEN PRINT "01-1"
IF PDPointCheck(cx, cy, LD_pick_01_02()) THEN PRINT "01-2"
IF PDPointCheck(cx, cy, LD_pick_01_03()) THEN PRINT "01-3"
IF PDPointCheck(cx, cy, LD_pick_01_04()) THEN PRINT "01-4"
IF PDPointCheck(cx, cy, LD_pick_01_05()) THEN PRINT "01-5"
IF PDPointCheck(cx, cy, LD_pick_01_06()) THEN PRINT "01-6"
IF PDPointCheck(cx, cy, LD_pick_01_07()) THEN PRINT "01-7"
IF PDPointCheck(cx, cy, LD_pick_01_08()) THEN PRINT "01-8"
IF PDPointCheck(cx, cy, LD_pick_01_09()) THEN PRINT "01-9"
IF PDPointCheck(cx, cy, LD_pick_01_10()) THEN PRINT "01-10"
IF PDPointCheck(cx, cy, LD_pick_01_11()) THEN PRINT "01-11"
IF PDPointCheck(cx, cy, LD_pick_01_12()) THEN PRINT "01-12"
IF PDPointCheck(cx, cy, LD_pick_01_13()) THEN PRINT "01-13"
IF PDPointCheck(cx, cy, LD_pick_01_14()) THEN PRINT "01-14"
IF PDPointCheck(cx, cy, LD_pick_01_15()) THEN PRINT "01-15"
IF PDPointCheck(cx, cy, LD_pick_01_16()) THEN PRINT "01-16"
IF PDPointCheck(cx, cy, LD_pick_02_01()) THEN PRINT "02-1"
IF PDPointCheck(cx, cy, LD_pick_02_02()) THEN PRINT "02-2"
IF PDPointCheck(cx, cy, LD_pick_02_03()) THEN PRINT "02-3"
IF PDPointCheck(cx, cy, LD_pick_02_04()) THEN PRINT "02-4"
IF PDPointCheck(cx, cy, LD_pick_02_05()) THEN PRINT "02-5"
IF PDPointCheck(cx, cy, LD_pick_02_06()) THEN PRINT "02-6"
IF PDPointCheck(cx, cy, LD_pick_02_07()) THEN PRINT "02-7"
IF PDPointCheck(cx, cy, LD_pick_02_08()) THEN PRINT "02-8"
IF PDPointCheck(cx, cy, LD_pick_02_09()) THEN PRINT "02-9"
IF PDPointCheck(cx, cy, LD_pick_02_10()) THEN PRINT "02-10"
IF PDPointCheck(cx, cy, LD_pick_02_11()) THEN PRINT "02-11"
IF PDPointCheck(cx, cy, LD_pick_02_12()) THEN PRINT "02-12"
IF PDPointCheck(cx, cy, LD_pick_02_13()) THEN PRINT "02-13"
IF PDPointCheck(cx, cy, LD_pick_02_14()) THEN PRINT "02-14"
IF PDPointCheck(cx, cy, LD_pick_02_15()) THEN PRINT "02-15"
IF PDPointCheck(cx, cy, LD_pick_02_16()) THEN PRINT "02-16"
IF PDPointCheck(cx, cy, LD_pick_03_01()) THEN PRINT "03-1"
IF PDPointCheck(cx, cy, LD_pick_03_02()) THEN PRINT "03-2"
IF PDPointCheck(cx, cy, LD_pick_03_03()) THEN PRINT "03-3"
IF PDPointCheck(cx, cy, LD_pick_03_04()) THEN PRINT "03-4"
IF PDPointCheck(cx, cy, LD_pick_03_05()) THEN PRINT "03-5"
IF PDPointCheck(cx, cy, LD_pick_03_06()) THEN PRINT "03-6"
IF PDPointCheck(cx, cy, LD_pick_03_07()) THEN PRINT "03-7"
IF PDPointCheck(cx, cy, LD_pick_03_08()) THEN PRINT "03-8"
IF PDPointCheck(cx, cy, LD_pick_03_09()) THEN PRINT "03-9"
IF PDPointCheck(cx, cy, LD_pick_03_10()) THEN PRINT "03-10"
IF PDPointCheck(cx, cy, LD_pick_03_11()) THEN PRINT "03-11"
IF PDPointCheck(cx, cy, LD_pick_03_12()) THEN PRINT "03-12"
IF PDPointCheck(cx, cy, LD_pick_03_13()) THEN PRINT "03-13"
IF PDPointCheck(cx, cy, LD_pick_03_14()) THEN PRINT "03-14"
IF PDPointCheck(cx, cy, LD_pick_03_15()) THEN PRINT "03-15"
IF PDPointCheck(cx, cy, LD_pick_03_16()) THEN PRINT "03-16"
IF PDPointCheck(cx, cy, LD_pick_04_01()) THEN PRINT "04-1"
IF PDPointCheck(cx, cy, LD_pick_04_02()) THEN PRINT "04-2"
IF PDPointCheck(cx, cy, LD_pick_04_03()) THEN PRINT "04-3"
IF PDPointCheck(cx, cy, LD_pick_04_04()) THEN PRINT "04-4"
IF PDPointCheck(cx, cy, LD_pick_04_05()) THEN PRINT "04-5"
IF PDPointCheck(cx, cy, LD_pick_04_06()) THEN PRINT "04-6"
IF PDPointCheck(cx, cy, LD_pick_04_07()) THEN PRINT "04-7"
IF PDPointCheck(cx, cy, LD_pick_04_08()) THEN PRINT "04-8"
IF PDPointCheck(cx, cy, LD_pick_04_09()) THEN PRINT "04-9"
IF PDPointCheck(cx, cy, LD_pick_04_10()) THEN PRINT "04-10"
IF PDPointCheck(cx, cy, LD_pick_04_11()) THEN PRINT "04-11"
IF PDPointCheck(cx, cy, LD_pick_04_12()) THEN PRINT "04-12"
IF PDPointCheck(cx, cy, LD_pick_04_13()) THEN PRINT "04-13"
IF PDPointCheck(cx, cy, LD_pick_04_14()) THEN PRINT "04-14"
IF PDPointCheck(cx, cy, LD_pick_04_15()) THEN PRINT "04-15"
IF PDPointCheck(cx, cy, LD_pick_04_16()) THEN PRINT "04-16"

RETURN
' *&&&&&&&&&&&&&*

SUB rotateset (pairslayout() AS LONG, start, finish, fulcX, fulcY, deg)

DIM pl_val(start TO finish, 0 TO 1) AS LONG
FOR i = start TO finish
 pl_val(i, 0) = pairslayout(i, 0) - fulcX
 pl_val(i, 1) = pairslayout(i, 1) - fulcY
NEXT i

FOR i = start TO finish

term# = pl_val(i, 0): IF term# = 0 THEN term# = .00001
at# = ATN(pl_val(i, 1) / term#)
au# = at# + pi * deg / 180

' x1 = v * cos(t)
''x2 = x1*cos(u)/cos(t)
    cterm# = COS(at#): IF cterm# = 0 THEN cterm# = .00001
    pl_val(i, 0) = CLNG(pl_val(i, 0) * COS(au#) / cterm#)

' y1 = v * sin(t)
''y2 = y1*sin(u)/sin(t)
    sterm# = SIN(at#): IF sterm# = 0 THEN sterm# = .00001
    pl_val(i, 1) = CLNG(pl_val(i, 1) * SIN(au#) / sterm#)

NEXT i

FOR i = start TO finish
 pairslayout(i, 0) = pl_val(i, 0) + fulcX
 pairslayout(i, 1) = pl_val(i, 1) + fulcY
NEXT i

END SUB


SUB FillBunch (lodSubset() AS LONG, label$, maxscale, multipass AS _FLOAT)
' ! can only be used for convex shapes!
SHARED fillhue&

np = UBOUND(lodSubset, 1)

IF __Get2(multipass, destHandle&, custcolor&) = 0 THEN
 custcolor& = _RGB32(255, 255, 255) ' set to a default drawing color
END IF

DIM CALM_linedat(0 TO np + 1, 0 TO 3) AS SINGLE
keepingd& = _DEST
_DEST destHandle&

  PDLineUpPoints lodSubset(), CALM_linedat()

FOR i = 0 TO np
  is = i + 1: IF is > np THEN is = 0
  LINE (lodSubset(i, 0), lodSubset(i, 1))-(lodSubset(is, 0), lodSubset(is, 1)), custcolor& OR &HFF000000 ''_RGB32(85, 85, 85)
NEXT i

'paint the inside of our shape only once...

 px = (lodSubset(0, 0) + lodSubset((np + 1) \ 2, 0)) / 2
 py = (lodSubset(0, 1) + lodSubset((np + 1) \ 2, 1)) / 2

 PAINT (px, py), fillhue&, custcolor& OR &HFF000000

_DEST keepingd&

END SUB

'$INCLUDE:'calmcompfunc.bas'

you might notice the source file size.  yeah that ended up just being a lot of copy-pasting... a LOT.  but I think the cool graphic was worth it. :>

the long term benefit of course is that you can have as many of the details of the interface of your program in your grasp as you want, even being able to change the graphical style as your needs change.  of course the potential for this sort of programming depends on your knowledge of geometry and handiness with the graphics commands of qbasic, though you still retain a lot of control by using layouts comprised entirely of positional points.
« Last Edit: January 12, 2011, 01:36:59 PM by Muffinman »

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
look - it sings, too!
« Reply #9 on: January 11, 2011, 06:16:20 PM »
You will need this layout file: musicex.png.  pressing the play button loads and sounds the muzac!

example- rocknroll
Code: [Select]
'$INCLUDE:'calmcompinit.bas'

SCREEN _NEWIMAGE(800, 600, 32)

REDIM notesdat(75, 2) AS LONG
REDIM inputdat(5, 2) AS LONG

inputdat(0, 0) = _WIDTH(_DEST) * .25: inputdat(1, 0) = inputdat(0, 0) + 31
inputdat(0, 1) = _HEIGHT(_DEST) * .3: inputdat(1, 1) = inputdat(0, 1) + 31
ShowBox inputdat(), 1, "  Play", 2.5, _DEST: LOCATE 15, 1: PRINT SPACE$(11) + "[ E S C ] to quit"
LOCATE 1, 1

DO: DO WHILE _MOUSEINPUT: LOOP
 plmb = lmb: lmb = _MOUSEBUTTON(1)
 cx = _MOUSEX: cy = _MOUSEY
 ink$ = INKEY$

 IF (plmb IMP lmb) = 0 THEN
  IF CheckPair(inputdat(), 1, cx, cy) THEN playon = -1
 END IF

 IF playon THEN
  ReadLayout notesdat(), "musicex.png", 0
  FOR i = 0 TO UBOUND(notesdat, 1): IF notesdat(i, 1) = 0 THEN ndEnd = i - 1: EXIT FOR
  NEXT i
  ArtificialPreserveL notesdat(), 0, ndEnd

  staffoffst% = 150 ' vertical staff offset
  noteduration = 5

  FOR subi = 0 TO 999
   FOR subi2 = 1 TO UBOUND(notesdat, 1)
     IF notesdat(subi2, 0) = subi THEN
       fqexp = (notesdat(subi2, 1) - staffoffst%) \ (notesdat(0, 1) / 2)
       SOUND 420 * (2 ^ (1 / 12)) ^ fqexp, noteduration
       PRINT fqexp; ' print the note #
       _DELAY (noteduration) / 18.5
     END IF
     ink$ = INKEY$: IF INSTR(ink$, CHR$(27)) THEN END
   NEXT subi2
  _DELAY .01
  NEXT subi
  playon = 0: PRINT
 END IF

LOOP UNTIL ink$ = CHR$(27)


'$INCLUDE:'calmcompfunc.bas'

uh well, what can I say?  he-he-he!  I was inspired to do this because the look of the flags is somewhat like music notes.  sometimes they look like the radical symbol, which fits well given their radical-ness.

the code reads the image as a chromatic scale, like a piano keyboard so you have ready access to all the flats/sharps.  because the loop here ignores actual ordering done by the ReadLayout function, one could modify it to assign varying durations based on flag color, and not be limited to all quarter notes.  but had I wanted more than one staff per layout pic I'd have to use a different process.

the pink flag's linked by its y- position to the width of the space between tones, but I realized later it might have been of more use if instead it marked the start pixel of tone 0

edit-
I put together a small no frills layout file-viewer program, just so you can check how your flags are interpreted for troubleshooting purposes.  try it with any of the layouts provided to get a quick numeric view.  to use: click the file name box and type, then click load or press enter; the arrow button moves the interface out of the way

example- Viewer
Code: [Select]
' - - CALM viewer - -
'Now with drag & drop support!
'$INCLUDE:'calmcompinit.bas'

_TITLE "CALM Layout Viewer"
bgScreen = _NEWIMAGE(1400, 600, 32)
SCREEN bgScreen, , 2, 0
hScrBuf& = _DEST
SCREEN bgScreen, , 1, 0
hScrGfx& = _DEST
SCREEN bgScreen, , 0, 0

DIM cc AS _INTEGER64, boxes(100, 2) AS LONG
'(the array to hold the coord/flag data must be LONG)
DIM layMyPage(lod_max_siz, 3) AS LONG

hoffs = INT(_WIDTH(bgScreen) * .8)
FOR i = 0 TO 11
 IF i > 4 AND i < 9 THEN i2 = 1 ELSE i2 = 0
 boxes(i * 2, 0) = hoffs - i2 * hoffs * .8
 boxes(i * 2, 1) = 120 + (i - i2 * 4) * 40
 boxes(i * 2 + 1, 0) = hoffs + 265 - i2 * hoffs * .8
 boxes(i * 2 + 1, 1) = 138 + (i - i2 * 4) * 40
NEXT i

dglscanMin = 3 ' override default values here
dglscanLen = 20

ext$ = ".bmp" ' will append if no extension type
lyFileSpec$ = "default_ly" + ext$ ' sets a display filename
IF LEN(COMMAND$) THEN lyFileSpec$ = COMMAND$: tx$ = lyFileSpec$: flagdoload = -1
tx$ = lyFileSpec$
buttonCap$ = "  -Load File- "
GOSUB pasteoverlay

pointnum = 100 ' number to print via ShowPrintout
animateclick = 80000

DO: DO: LOOP WHILE _MOUSEINPUT
  charin$ = INKEY$
  prevlmb = lmb: lmb = _MOUSEBUTTON(1)

  ' v v v --this catch routine is specific to the event 'animinvalid'
  IF (cc MOD animateclick = animinvalid.time##) AND (animinvalid > 0) THEN
   animinvalid = animinvalid - 1
   IF animinvalid = 0 THEN flaganiminvalid = -1
  END IF


  IF LEN(charin$) = 1 AND charin$ <> CHR$(13) AND typetarget = 1 THEN
    IF charin$ = CHR$(8) AND tx$ = "" THEN charin$ = "": SOUND 390, 1.5
    IF charin$ = CHR$(8) THEN tx$ = LEFT$(tx$, LEN(tx$) - 1) ELSE tx$ = tx$ + charin$
    GOSUB pasteoverlay
    LINE (boxes(2, 0) - 2, boxes(2, 1) - 2)-(boxes(3, 0) + 2, boxes(3, 1) + 2), _RGB32(140, 75, 75), B

  END IF

  IF (prevlmb IMP lmb) = 0 THEN
        IF CheckPair(boxes(), 2, _MOUSEX, _MOUSEY) THEN
         IF lyFileSpec$ = "default_ly" + ext$ THEN tx$ = "": lyFileSpec$ = "": GOSUB pasteoverlay
         typetarget = 1
         LINE (boxes(2, 0) - 2, boxes(2, 1) - 2)-(boxes(3, 0) + 2, boxes(3, 1) + 2), _RGB32(140, 75, 75), B
        ELSE
         typetarget = 0
         LINE (boxes(2, 0) - 2, boxes(2, 1) - 2)-(boxes(3, 0) + 2, boxes(3, 1) + 2), _RGB32(0, 0, 0), B
        END IF
      IF CheckPair(boxes(), 3, _MOUSEX, _MOUSEY) THEN flagdoload = -1
      IF CheckPair(boxes(), 4, _MOUSEX, _MOUSEY) THEN
        ' swap boxes()  2<->6 ;  boxes()  3<->7 ;  boxes()  4<->8
        FOR i = 2 TO 7
         SWAP boxes(i, 0), boxes(i + 8, 0)
         SWAP boxes(i, 1), boxes(i + 8, 1)
        NEXT i
        overlayloc%% = overlayloc%% XOR -1
        GOSUB pasteoverlay
      END IF

  END IF
 IF flagdoload OR (charin$ = CHR$(13) AND typetarget = 1) THEN
  flagdoload = 0
  IF LEN(tx$) > 0 THEN
      IF INSTR(tx$, ".") = 0 THEN tx$ = tx$ + ext$
      lyFileSpec$ = tx$
  END IF
  flagrlfail = 0
  ON ERROR GOTO 1
  ReadLayout layMyPage(), lyFileSpec$, 0
  rlfail:
      ON ERROR GOTO 95
  IF NOT flagrlfail THEN
   ShowPrintout
   GOSUB pasteoverlay
     ELSE
       animinvalid = 5: animinvalid.time## = cc MOD animateclick
  END IF
 END IF


  ' v v v --this display routine is specific to the event 'animinvalid'
  IF (animinvalid > 0 OR flaganiminvalid) AND (animinvalid.framestate% <> animinvalid) THEN
   IF animinvalid MOD 2 = 1 THEN buttonCap$ = "invalid" ELSE buttonCap$ = ""
   IF flaganiminvalid THEN flaganiminvalid = 0: buttonCap$ = "  -Load File- "
   GOSUB pasteoverlay
   animinvalid.framestate% = animinvalid

  END IF


  cc = cc + 1 ' increment the timing var

LOOP UNTIL charin$ = CHR$(27)

END

1 flagrlfail = -1
RESUME rlfail

95 BEEP
 PRINT "unknown error"
 SLEEP
END ' error traps

pasteoverlay:
PCOPY 2, 0
_DEST hScrGfx&
CLS , _RGB(96, 96, 128)

ShowBox boxes(), 2, tx$, 2.5, _DEST
ShowBox boxes(), 3, buttonCap$, 2, _DEST
ShowBox boxes(), 4, "    " + CHR$(17 + overlayloc%%), 2, _DEST
_DEST bgScreen

FOR subi = 2 TO 4
 BoxBufCopy boxes(), subi, hScrBuf&
 BoxBufCopy boxes(), subi, hScrGfx&
NEXT subi

RETURN


SUB ShowPrintout
SHARED layMyPage() AS LONG, pointnum

' display printout of the first few flags
 colnum% = 8
 dispblanklines = 1
 CLS , 0
 FOR a = 0 TO pointnum \ colnum%
   FOR b = 0 TO colnum% - 1
     COLOR &HFFFFFFFF
     LOCATE a + 1 + dispblanklines, b * 19 + 1: PRINT layMyPage(a * colnum% + b, 0); layMyPage(a * colnum% + b, 1); " ";
     COLOR layMyPage(a * colnum% + b, 2)
     PRINT HEX$(layMyPage(a * colnum% + b, 2))
   NEXT b
 NEXT a

COLOR &HFFFFFFFF
PCOPY 0, 2

END SUB

SUB BoxBufCopy (pairslayout() AS LONG, idx, hSource AS LONG)

cx0 = pairslayout(2 * idx - 2, 0): cx1 = pairslayout(2 * idx - 1, 0)
cy0 = pairslayout(2 * idx - 2, 1): cy1 = pairslayout(2 * idx - 1, 1)
_PUTIMAGE (cx0, cy0)-(cx1, cy1), hSource, , (cx0, cy0)-(cx1, cy1)

END SUB

'$INCLUDE: 'calmcompfunc.bas'
« Last Edit: March 30, 2011, 10:31:07 PM by Muffinman »

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
Re: Cartesian Active Layout Mapper, a general purpose library
« Reply #10 on: March 11, 2011, 10:49:31 AM »
I celebrate my 100th post in the forum.

thought about how to use it and couldn't come up with anything better than bumping my cool library thread.  by 1 place, that's right.  *hip THRUST!!*-UNHH!