Attribute VB_Name = "ModMaths"
' ModMaths.bas

Option Explicit

Private Type RECT
    Left As Long
    TOp As Long
    Right As Long
    Bottom As Long
End Type

Private REC As RECT

Private Declare Function PtInRect Lib "USER32" _
   (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long

Private Declare Function SetRect Lib "USER32" _
(lpRect As RECT, ByVal x1 As Long, ByVal y1 As Long, _
  ByVal x2 As Long, ByVal y2 As Long) As Long
  
'Private REC As RECT
'SetRect REC, 0, 0, FullW - 1, FullH - 1
'If PtInRect(REC, XX, YY) <> 0 Then

' Cirlipse
Public zrad As Single, zratio As Single
Public zradx As Single, zrady As Single
Public zrad2 As Single   ' For Radials
' pi constant
Public Const pi# = 3.1415926536
Public Const d2r# = pi# / 180
Public Const r2d# = 180 / pi#


Public Function Rand(ByVal Min As Long, ByVal Max As Long) As Long
   ' Returns random integer value Min to Max inclusive
   Rand = CLng((Max - Min + 1) * Rnd + Min)
End Function

Public Function ArcCos(xijzA As Single) As Single
' Input
' Const pi#
' xijzA = (xi/zA) or (xj/zA)

' Inverse functions from VB Help
' Cosine Arccos(X) = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1)
' Returns 0 to pi
Dim x As Single, xsq As Single
    xsq = (1 - xijzA * xijzA)
    If xsq <= 0 Then
      x = 0.0000000001
    Else
      x = Sqr(xsq)
    End If
    ArcCos = Atn(-xijzA / x) + pi# / 2
End Function


Public Function zATan2(ByVal zy As Single, ByVal zx As Single) As Single
' Public pi# = Const
' 0 degrees to right
' Find angle arctan from -pi# to +pi#
   If zx <> 0 Then
      zATan2 = Atn(zy / zx)
      If (zx < 0) Then  ' Want +pi# when zY=0
         If (zy < 0) Then zATan2 = zATan2 - pi# Else zATan2 = zATan2 + pi#
      End If
   Else  ' zx=0
      zATan2 = Sgn(zy) * pi# / 2
   End If
End Function

Public Function zAng(ByVal zy As Single, ByVal zx As Single) As Single

' pi# = Const
' 0 degrees to right
' Gives anti-clockwise angles 0 -> 2*pi#
' Setting zy = -zy on entry gives clockwise angles

If zy = 0 Then
   If zx >= 0 Then zAng = 0 Else zAng = pi#
Else
   zAng = Atn(zx / zy) + pi# / 2
   If zy > 0 Then zAng = zAng + pi#
End If
' To convert to degrees zAng = zAng * 180 / pi#

End Function

Public Sub GetParallelCoords(zspace As Single, _
   ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single, _
   ixa As Single, iya As Single, ixb As Single, iyb As Single, _
   Optional ixc As Single, Optional iyc As Single, Optional ixd As Single, Optional iyd As Single, _
   Optional cosA As Single = 0, Optional sinA As Single = 0)



'  GetParallelCoords (IN) zspace,X1,Y1,X2,Y2, (OUT)ixa,iya,ixb,iyb,+Optionals

' IN:  zspace,X1,Y1,X2,Y2  { here xsto(k),ysto(k) -> xsto(k+1),ysto(k+1) }
' OUT: ixa,iya,ixb,iyb   to left of line  X1,Y1->X2,Y2
'      ixc,iyc,ixd,iyd   to right of line X1,Y1->X2,Y2,cosA,sinA

'                     X2,Y2
'          ixb,iyb/  o            ixd,iyd/
'                /  /                   /
'               /  /                   /
'              /  /                   /
'      Left   /  /                   / Right
'           </- /                   /
'           / -/> zspace           /
'          /  /                   /
'         /  /                   /
' ixa,iya/  /            ixc,iyc/
'          o X1,Y1

Dim xd As Single, yd As Single
Dim xdd As Single, ydd As Single
Dim zalpha1 As Single

   xd = x2 - x1
   yd = y2 - y1
   If xd = 0 And yd = 0 Then
      ixa = x1: iya = y1
      ixb = x1: iyb = y2
      ixc = x1: iyd = y1
      ixd = x1: iyd = y2
      cosA = 0: sinA = 0
   Else
      zalpha1 = zATan2(yd, xd)
      cosA = Cos(zalpha1)
      sinA = Sin(zalpha1)
      xdd = zspace * sinA
      ydd = zspace * cosA
      ixa = x1 + xdd: iya = y1 - ydd
      ixb = x2 + xdd: iyb = y2 - ydd
      
      ixc = x1 - xdd: iyc = y1 + ydd
      ixd = x2 - xdd: iyd = y2 + ydd
   End If
End Sub

Public Sub Get2LineIntersect(ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single, _
                             ByVal x3 As Single, ByVal y3 As Single, ByVal x4 As Single, ByVal y4 As Single, _
                             xout As Single, yout As Single)

Dim zm1 As Single, zc1 As Single
Dim zm2 As Single, zc2 As Single

' Get intersection of lines xy1-xy2 & xy3-xy4
   If x2 - x1 <> 0 Then
      zm1 = (y2 - y1) / (x2 - x1)
   Else
      zm1 = 10000 * Sgn(y2 - 11)
   End If
   If Abs(zm1) < 0.0001 Then zm1 = 0.0001 * Sgn(y2 - y1)
   zc1 = y2 - zm1 * x2
   
   If x4 - x3 <> 0 Then
      zm2 = (y4 - y3) / (x4 - x3)
   Else
      zm2 = 10000 * Sgn(y4 - y3)
   End If
   If Abs(zm2) < 0.0001 Then zm2 = 0.0001 * Sgn(y4 - y3)
   zc2 = y3 - zm2 * x3
   
   If zm1 <> zm2 Then
      If zm1 = -zm2 Then  ' Right angle lines
         xout = x1
         yout = y1
      Else
         xout = (zc2 - zc1) / (zm1 - zm2)
         yout = (zm2 * zc1 - zm1 * zc2) / (zm2 - zm1)
      End If
   
   Else  ' Parallel lines
      xout = x1
      yout = y1
   End If
   
   If xout < -2000 Then xout = -2000
   If xout > 2000 Then xout = 2000
   If yout < -2000 Then yout = -2000
   If yout > 2000 Then yout = 2000
   

End Sub

Public Sub GetIntersections()

' Public zspace
' Public x/ysto(1) to PointCount

' IN:  3 x/ysto() points
' OUT: 6 pts either side of x/ysto() points

''''''''' Intersections, Ends, Shades
'          ix1,iy1
'            . .
'           .   .
'          .     .
'         .   .<--------- ix2,iy2
'        .   . .   .
'      b/  d/  e\  g\
'      /   /     \   \
'     /   /       \   \
'   a/  c/        f\  h\
Dim k As Long
Dim ix1 As Single, iy1 As Single    ' Intersection point1
Dim ix2 As Single, iy2 As Single    ' Intersection point2
Dim zL As Single, theta As Single ' For shift back
Dim zdx As Single, zdy As Single

   For k = 2 To PointCount
      GetIntersection6Pts zspace, _
            xsto(k - 1), ysto(k - 1), _
            xsto(k), ysto(k), _
            xsto(k + 1), ysto(k + 1), _
            ixa, iya, ixb, iyb, _
            ixc, iyc, ixd, iyd, _
            ix1, iy1, ix2, iy2, _
            ixe, iye, ixf, iyf, _
            ixg, iyg, ixh, iyh
            
      If k = 2 Then
         pxstoL(1) = ixa: pystoL(1) = iya
         pxstoR(1) = ixc: pystoR(1) = iyc
         If k = PointCount Then
            pxstoL(PointCount) = ixb: pystoL(PointCount) = iyb
            pxstoR(PointCount) = ixd: pystoR(PointCount) = iyd
            Exit For
         End If
      End If
      If k = PointCount - 1 Then
         
         pxstoL(k) = ix1: pystoL(k) = iy1
         pxstoR(k) = ix2: pystoR(k) = iy2
         pxstoL(PointCount) = ixf: pystoL(PointCount) = iyf
         pxstoR(PointCount) = ixh: pystoR(PointCount) = iyh
         Exit For
      End If
      pxstoL(k) = ix1: pystoL(k) = iy1
      pxstoR(k) = ix2: pystoR(k) = iy2
   Next k
   
   ' Shift back so R points on x/ysto() points
   For k = 1 To PointCount
      zdx = xsto(k) - pxstoR(k)
      zdy = ysto(k) - pystoR(k)
      zL = zdx ^ 2 + zdy ^ 2
      zL = Sqr(zL)
'      zL = Sqr((xsto(k) - pxstoR(k)) * (xsto(k) - pxstoR(k)) _
'            + (ysto(k) - pystoR(k)) * (ysto(k) - pystoR(k)))
      theta = zATan2(ysto(k) - pystoR(k), xsto(k) - pxstoR(k))
      zdx = zL * Cos(theta)
      zdy = zL * Sin(theta)
      pxstoR(k) = pxstoR(k) + zdx
      pystoR(k) = pystoR(k) + zdy
      pxstoL(k) = pxstoR(k) + 2 * zdx
      pystoL(k) = pystoR(k) + 2 * zdy
   Next k

'   ' Draw whole poly
'   For k = 1 To PointCount - 1
'      picDRAW.Line (pxstoL(k), pystoL(k))-(pxstoL(k + 1), pystoL(k + 1)), Cul
'      picDRAW.Line (pxstoR(k), pystoR(k))-(pxstoR(k + 1), pystoR(k + 1)), Cul
'   Next k
End Sub

Public Sub GetIntersection6Pts(ByVal zspace As Single, _
            ByVal x1 As Single, ByVal y1 As Single, _
            ByVal x2 As Single, ByVal y2 As Single, _
            ByVal x3 As Single, ByVal y3 As Single, _
            ixa As Single, iya As Single, ixb As Single, iyb As Single, _
            ixc As Single, iyc As Single, ixd As Single, iyd As Single, _
            ix1 As Single, iy1 As Single, ix2 As Single, iy2 As Single, _
            ixe As Single, iye As Single, ixf As Single, iyf As Single, _
            ixg As Single, iyg As Single, ixh As Single, iyh As Single)


' zspace(double line spacing)

'Here FullW picDRAW.Width, FullH = picDRAW.Height
'In:  xsto(k-1),ysto(k-1) -> xsto(k),ysto(k) -> xsto(k+1),ysto(k+1)

'OR

'IN:   zspace,X1,Y1,X2,Y2,X3,Y3,
'OUT:  ixa,iya,ixb,iyb,ixc,iyc,,ixd,iyd,
'      ix1,iy1,ix2,iy2,
'      ixe,iye,ixf,iyf,ixg,iyg,ixh,iyh


' Geometry
'              ix1,iy1                         ixc,iyc ixa,iya ixf,iyf ixh,iyh
'                /\                                  \  1  \    /  3  /
'                                                    -\  .  \  /  .  /-
'              /    \                                  \  .  \/<---------ix2,iy2
'             /  ..<-----------X2,Y2                    \  .    .  /
'            /  .  .  \                                  \  .  .  /
'   ixb,iyb-/  .    .  \-ixe,iye                          \  .2  /
'          /  .  /\<-----------ix2,iy2                     \    /
'         /  .  /  \  .  \                                  \  /
'ixa,iya /  .  /    \  .  \ixf,iyf                           \/
'     X1,Y1.  /      \  .<-----------X3,Y3                 ix1,iy1
'         ixc,iyc ixh,iyh

'       \3     .                                          b/          \e
'     zm3\    .                                           /  .      .  \
'     zc3 \  .                                           /  .  /d \g .  \
'          \__zm3 zc3_______3                           /  .  /    \  .  \
'          /2                                          /  .  /      \  .  \
'      zm1/                                           /  .  /        \  .  \
'     zc1/     Point 3 to left or Right              /  .  /          \  .  \
'       /      of Line 1 -> 2                      a/  .  /            \  .  \f
'      /1                                                /c             \h

' Reverse intersections have problems??

' Slopes & Cuts
Dim zm1 As Single, zc1 As Single
Dim zm2 As Single, zc2 As Single
Dim zm3 As Single, zc3 As Single   ' Extra for debugging
Dim zm4 As Single, zc4 As Single

'Dim zperp As Single

' 4 parallel points either side of lines 1->2
'ixa, iya
'ixb, iyb
'ixc, iyc
'ixd, iyd
' 4 parallel points either side of lines 2->3
'ixe, iye
'ixf, iyf
'ixg, iyg
'ixh, iyh
   
   'zspace = zspace / 2

   GetParallelCoords zspace / 2, x1, y1, x2, y2, ixa, iya, ixb, iyb, ixc, iyc, ixd, iyd
   GetParallelCoords zspace / 2, x2, y2, x3, y3, ixe, iye, ixf, iyf, ixg, iyg, ixh, iyh
   
   ' Get intersection of lines a-b & e-f
   If ixb - ixa <> 0 Then
      zm1 = (iyb - iya) / (ixb - ixa)
   Else
      zm1 = 10000 * Sgn(iyb - iya)
   End If
   If Abs(zm1) < 0.0001 Then zm1 = 0.0001 * Sgn(iyb - iya)
   zc1 = iya - zm1 * ixa
   
   If ixf - ixe <> 0 Then
      zm2 = (iyf - iye) / (ixf - ixe)
   Else
      zm2 = 10000 * Sgn(iyf - iye)
   End If
   If Abs(zm2) < 0.0001 Then zm2 = 0.0001 * Sgn(iyf - iye)
   zc2 = iye - zm2 * ixe
   
   If zm1 <> zm2 Then
      ix1 = (zc2 - zc1) / (zm1 - zm2)
      iy1 = (zm2 * zc1 - zm1 * zc2) / (zm2 - zm1) ' k left
   Else
      ix1 = ixb
      iy1 = iyb
   End If
   
   ' Get intersection of lines c-d & g-h
   If ixd - ixc <> 0 Then
     zm3 = (iyd - iyc) / (ixd - ixc)
   Else
      zm3 = 10000 * Sgn(iyd - iyc)
   End If
   If Abs(zm3) < 0.0001 Then zm3 = 0.0001 * Sgn(iyd - iyc)
   zc3 = iyc - zm3 * ixc
   
   If ixh - ixg <> 0 Then
      zm4 = (iyh - iyg) / (ixh - ixg)
   Else
      zm4 = 10000 * Sgn(iyh - iyg)
   End If
   If Abs(zm4) < 0.0001 Then zm4 = 0.0001 * Sgn(iyh - iyg)
   zc4 = iyg - zm4 * ixg
   If zm3 <> zm4 Then
      ix2 = (zc4 - zc3) / (zm3 - zm4)
      iy2 = (zm4 * zc3 - zm3 * zc4) / (zm4 - zm3)   ' k right
   Else
      ix2 = ixg
      iy2 = iyg
   End If
   
   ixg = FullW
   iyg = FullH
   
   If ix1 > 3 * FullW / 2 Then ix1 = 3 * FullW / 2
   If ix1 < -3 * FullW / 2 Then ix1 = -3 * FullW / 2
   If ix2 > 3 * FullW / 2 Then ix1 = 3 * FullW / 2
   If ix2 < -3 * FullW / 2 Then ix1 = -3 * FullW / 2

   If iy1 > 3 * FullH / 2 Then iy1 = 3 * FullH / 2
   If iy1 < -3 * FullH / 2 Then iy1 = -3 * FullH / 2
   If iy2 > 3 * FullH / 2 Then iy1 = 3 * FullH / 2
   If iy2 < -3 * FullH / 2 Then iy1 = -3 * FullH / 2
   
   
   ' Arbitrary limiting ?
'   If ix1 > 500 Then ix1 = 500
'   If ix1 < -500 Then ix1 = -500
'
'   If iy1 > 500 Then iy1 = 500
'   If iy1 < -500 Then iy1 = -500
'
'   If ix2 > 500 Then ix2 = 500
'   If ix2 < -500 Then ix2 = -500
'
'   If iy2 > 500 Then iy2 = 500
'   If iy2 < -500 Then iy2 = -500
End Sub

Public Sub EvalCirlipse(ByVal xs As Single, ByVal ys As Single, _
         ByVal xe As Single, ByVal ye As Single, Optional ByVal spacing As Single = 0)

'Public zrad As Single, zratio As Single
'Public zradx As Single, zrady As Single

' Cirlipse
' EvalCirlipse xsto(1), ysto(1), xsto(2), ysto(2)
'                  xs,ys start, xe,ye end
' Returns Public zrad,zratio,zradx,zrady

If spacing <> 0 Then   ' Concentric ellipses for +DX
'' Original when finding inner ring
''   ye = ye - spacing   ' else lunes or eyes
''   If xe > xs Then
''      xe = xe - spacing
''   Else
''      xe = xe + spacing
''   End If
'
'   ' Finding outer ring
   ye = ye + spacing   ' else lunes or eyes
   If xe >= xs Then
      'If zrad = 0 Then
         xe = xe + spacing
      'Else
      '   xe = xe + spacing * (xe - xs) / zrad
      'End If
   Else
      'If zrad = 0 Then
         xe = xe - spacing
      'Else
      '   xe = xe - spacing * (xs - xe) / zrad
      'End If
   End If
'
End If

   zradx = Abs(xe - xs)
   zrady = Abs(ye - ys)
   
If zradx >= zrady Then
   ye = ye + spacing
      If zradx = 0 Then
         xe = xe + spacing
      Else
         xe = xe + spacing * PixelSize * (xe - xs) / zradx
      End If
Else   ' zradx >= zrady
   xe = xe + spacing
      If zrady = 0 Then
         ye = ye + spacing
      Else
         ye = ye + spacing * PixelSize * (ye - ys) / zrady
      End If
End If

'   zradx = Abs(xe - xs)
'   zrady = Abs(ye - ys)

   
   If zradx = 0 Then
      zrad = zrady
      zratio = 10
   ElseIf zradx >= zrady Then
      zrad = zradx
      zratio = zrady / zradx
   Else  'zradx<zrady
      zrad = zrady
      zratio = zrady / zradx
   End If
End Sub

Public Sub GenerateCurvyPoints(xsto() As Long, ysto() As Long, PointCount As Long)
Dim xfrac As Single
Dim i As Long
Dim S As Long
Dim SUP As Long
Dim oldpts As Long
Dim newpts As Long
Dim xaa() As Single, yaa() As Single
Dim xdx As Single, ydy As Single

   xfrac = 0.25
   If CurvyLineTool = [CSolid] Then
      SUP = 3
   Else
      SUP = 2  '3
   End If
   oldpts = PointCount
   For S = 1 To SUP
       ReDim xaa(1 To oldpts), yaa(1 To oldpts)
       For i = 1 To oldpts
           xaa(i) = xsto(i): yaa(i) = ysto(i)
       Next i
       newpts = 2 * oldpts - 2
       If newpts = 0 Then newpts = 1   '??
       ReDim xsto(1 To newpts), ysto(1 To newpts)
       xsto(1) = xaa(1)
       ysto(1) = yaa(1)
       
       For i = 2 To oldpts - 1
           xdx = xaa(i) - xaa(i - 1)
           xsto(2 * i - 2) = xaa(i) - xfrac * xdx
           ydy = yaa(i) - yaa(i - 1)
           ysto(2 * i - 2) = yaa(i) - xfrac * ydy
           
           xdx = xaa(i + 1) - xaa(i)
           xsto(2 * i - 1) = xaa(i) + xfrac * xdx
           ydy = yaa(i + 1) - yaa(i)
           ysto(2 * i - 1) = yaa(i) + xfrac * ydy
       Next i
       
       xsto(newpts) = xaa(oldpts)
       ysto(newpts) = yaa(oldpts)
       oldpts = newpts
   Next S
   PointCount = newpts
End Sub

'Public Sub EvalTangents(ByVal kxc As Long, ByVal kyc As Long, ByVal zradius As Single, ByVal kxp As Long, ByVal kyp As Long, _
'                        kx1 As Single, ky1 As Single, kx2 As Single, ky2 As Single)
''IN: Circle centre = kxc,kyc  radius = zradius, external = kxp,kyp
''OUT: Tangents kxp,kyp to kx1,ky1 & kx2,ky2
'Dim zL As Single, zL2 As Single, zD As Single
'   zL2 = (kxp - kxc) * (kxp - kxc) + (kyp - kyc) * (kyp - kyc)
'   zL = Sqr(zL2)
'   If zL > zradius Then
'      zD = Sqr(zL2 - zradius * zradius)
'      kx1 = kxp - zD * ((kxp - kxc) * zD - (kyp - kyc) * zradius) / zL2 '+ 1
'      ky1 = kyp - zD * ((kyp - kyc) * zD + (kxp - kxc) * zradius) / zL2 '+ 1
'      kx2 = kxp - zD * ((kxp - kxc) * zD + (kyp - kyc) * zradius) / zL2 '+ 1
'      ky2 = kyp + zD * (-(kyp - kyc) * zD + (kxp - kxc) * zradius) / zL2 ' + 1
'   Else  'xp,yp inside circle
'      kx1 = kxp: ky1 = kyp
'      kx2 = kxc: ky2 = kyc
'   End If
'End Sub

'Public Sub EvalDiameters(ByVal kxs As Long, ByVal kys As Long, ByVal zradius As Single, ByVal kxp As Long, ByVal kyp As Long, _
'      kx1 As Long, ky1 As Long, kx2 As Long, ky2 As Long, kx3 As Long, ky3 As Long, kx4 As Long, ky4 As Long)

Public Sub EvalDiameters(ByVal kxs As Long, ByVal kys As Long, ByVal zradius As Single, ByVal kxp As Long, ByVal kyp As Long, _
      kx1 As Single, ky1 As Single, kx2 As Single, ky2 As Single, kx3 As Single, ky3 As Single, kx4 As Single, ky4 As Single)
'IN: Circ1: kxs,kys,zradius  Circ2: kxp,kyp,zradius both same radius
'OUT: Circ1 diam cords: kx1,ky1 -> kx3,ky3  Circ2 diam coords kx2,ky2 -> kx4,ky4
Dim zTheta As Single
   zTheta = zATan2(kyp - kys, kxp - kxs)
   kx1 = kxs + CInt(zradius * Sin(zTheta))
   ky1 = kys - CInt(zradius * Cos(zTheta))
   kx2 = kxs - CInt(zradius * Sin(zTheta))
   ky2 = kys + CInt(zradius * Cos(zTheta))
   
   kx3 = kxp + CInt(zradius * Sin(zTheta))
   ky3 = kyp - CInt(zradius * Cos(zTheta))
   kx4 = kxp - CInt(zradius * Sin(zTheta))
   ky4 = kyp + CInt(zradius * Cos(zTheta))
End Sub



Public Sub BresBoxFill(ByVal ix1 As Long, ByVal iy1 As Long, _
                  ByVal ix2 As Long, ByVal iy2 As Long, Cul As Long, _
                  Optional ByVal psize As Long = 1, Optional ByVal Convert As Long = 0)
   
' IN EG: BresBoxFill  picDATA(), xsto(1), ysto(1), xsto(2), ysto(2), LeftColor
' psize operational PixelSize

'** Publics picDATA(), xlo, ylo
'** Plus clipping on 0 to FullW-1, 0 to FullH-1
Dim iix As Long, iiy As Long
Dim ixx As Long, iyy As Long
Dim kxstep As Long, kystep As Long
Dim RR As Byte, RG As Byte, RB As Byte
Dim kadd As Long
   LngToRGB Cul, RR, RG, RB
   ' Adjust picDRAW coords to picDATA() coords
   ' xlo and ylo increments set by main scoll-bars in
   ' ModZoomScroll. Public Sub FixSBars_and_picDRAW(frm As Form)
   If Convert > 0 Then
      ix1 = ix1 + xlo
      iy1 = Form1.picDRAW.Height - iy1 + ylo
      ix2 = ix2 + xlo
      iy2 = Form1.picDRAW.Height - iy2 + ylo
   End If
   
      kystep = 1
      If iy1 > iy2 Then kystep = -1
      kxstep = 1
      If ix1 > ix2 Then kxstep = -1
      kadd = kystep
      If (iy1 = iy2) And psize <> 2 Then kadd = 0
      For iiy = iy1 To iy2 + kadd Step kystep
      For iix = ix1 To ix2 Step kxstep
         ' Reject any point outside
         If (iix >= 0 And iix <= FullW - 1) And (iiy >= 0 And iiy <= FullH - 1) Then
         
            If aSelectAccepted Then
               If (iix >= LOX And iix <= HIX) And (iiy >= LOY And iiy <= HIY) Then
                  If Not aExternal Then   ' Internal
                        If MaskArray(iix - LOX, iiy - LOY) = 0 Then BresBoxFillCALC iix, iiy, RB, RG, RR
                  Else  ' External
                        If MaskArray(iix - LOX, iiy - LOY) <> 0 Then BresBoxFillCALC iix, iiy, RB, RG, RR
                  End If
               Else
                  If aExternal Then BresBoxFillCALC iix, iiy, RB, RG, RR
               End If
            Else
               BresBoxFillCALC iix, iiy, RB, RG, RR
            End If
            
         End If
      Next iix
      'If pxsv = 1 Then Exit For
      Next iiy

End Sub
Private Sub BresBoxFillCALC(iix As Long, iiy As Long, RB As Byte, RG As Byte, RR As Byte)
   picDATA(0, iix, iiy) = RB
   picDATA(1, iix, iiy) = RG
   picDATA(2, iix, iiy) = RR
End Sub


Public Sub BresBox(ByVal ix1 As Single, ByVal iy1 As Single, ByVal ix2 As Single, ByVal iy2 As Single, _
   Cul As Long, Optional ND As Long = 1, Optional Convert As Long = 0)

' IN EG: BresBox xsto(1), ysto(1), xsto(2), ysto(2), LeftColor, PixelSize
' ND = lines' thickness

'** Publics picDATA(), xlo, ylo
'** Plus clipping on 0 to FullW-1, 0 to FullH-1
Dim n As Long

Dim iix As Single, iiy As Single
Dim kxstep As Single, kystep As Single
Dim RR As Byte, RG As Byte, RB As Byte
Dim nR As Long

   LngToRGB Cul, RR, RG, RB
   ' Adjust picDRAW coords to picDATA() coords
   ' xlo and ylo increments set by main scoll-bars in
   ' ModZoomScroll. Public Sub FixSBars_and_picDRAW(frm As Form)
   If Convert = 0 Then
   ix1 = ix1 + xlo
   iy1 = Form1.picDRAW.Height - iy1 + ylo
   ix2 = ix2 + xlo
   iy2 = Form1.picDRAW.Height - iy2 + ylo
   End If
   
   ' Move in half-thickness NB opposite expected increment for y
   kystep = 1
   If iy1 > iy2 Then kystep = -1
   kxstep = 1
   If ix1 > ix2 Then kxstep = -1
   ix1 = ix1 + kxstep * ND \ 2
   iy1 = iy1 + kystep * ND \ 2
   ix2 = ix2 - kxstep * ND \ 2
   iy2 = iy2 - kystep * ND \ 2
   
   For n = 0 To ND - 1
      nR = n / 2        ' ROUND corners will be done with DrawDot
      If Not aRound Then nR = 0  ' SQUARE
      'kystep = 1
      'If iy1 > iy2 Then kystep = -1
      ' avh = 0 Area, 1 VL, 2 VR, 3 HT, 4 HB

      For iiy = iy1 - nR To iy2 + nR Step kystep
         ' Reject any point outside picDATA()
         If iiy >= 0 And iiy <= FullH - 1 Then
            If ix1 >= 0 And ix1 <= FullW - 1 Then
                  picDATA(0, ix1, iiy) = RB   ' Left line
                  picDATA(1, ix1, iiy) = RG
                  picDATA(2, ix1, iiy) = RR
            End If
            If ix2 >= 0 And ix2 <= FullW - 1 Then
                  picDATA(0, ix2, iiy) = RB   ' Right line
                  picDATA(1, ix2, iiy) = RG
                  picDATA(2, ix2, iiy) = RR
            End If
         End If
      Next iiy
      
      
      ' May not want AA for Horz & Vert lines !!!
      If aAA Then
         For iiy = iy1 - nR To iy2 + nR Step kystep
            If iiy >= 0 And iiy <= FullH - 1 Then
               If ix1 - 0.5 >= 0 And ix1 + 0.5 <= FullW - 1 Then
                  AntiAlias picDATA(), ix1 - 0.5, iiy, Cul, 0, 0 '1
                  AntiAlias picDATA(), ix1 + 0.5, iiy, Cul, 0, 0 '1
               End If
               If ix2 - 0.5 >= 0 And ix2 + 0.5 <= FullW - 1 Then
                  AntiAlias picDATA(), ix2 - 0.5, iiy, Cul, 0, 0 '1
                  AntiAlias picDATA(), ix2 + 0.5, iiy, Cul, 0, 0 '1
               End If
            End If
         Next iiy
      End If
      
      'kxstep = 1
      'If ix1 > ix2 Then kxstep = -1
      
      For iix = ix1 + nR To ix2 - nR Step kxstep
         ' Reject any point outside picDATA
         If iix >= 0 And iix <= FullW - 1 Then
            If iy1 >= 0 And iy1 < FullH - 1 Then
               picDATA(0, iix, iy1) = RB   ' Top line
               picDATA(1, iix, iy1) = RG
               picDATA(2, iix, iy1) = RR
            End If
            If iy2 >= 0 And iy2 < FullH - 1 Then
               picDATA(0, iix, iy2) = RB  ' Bottom line
               picDATA(1, iix, iy2) = RG
               picDATA(2, iix, iy2) = RR
            End If
         End If
      Next iix
      
      ' May not want AA for Horz & Vert lines !!!
      If aAA Then
         For iix = ix1 + nR To ix2 - nR Step kxstep
            If iix >= 0 And iix <= FullW - 1 Then
               If iy1 - 0.5 >= 0 And iy1 + 0.5 < FullH - 1 Then
                  AntiAlias picDATA(), iix, iy1 - 0.5, Cul, 0, 0 '1
                  AntiAlias picDATA(), iix, iy1 + 0.5, Cul, 0, 0 '1
               End If
               If iy2 - 0.5 >= 0 And iy2 + 0.5 < FullW - 1 Then
                  AntiAlias picDATA(), iix, iy2 - 0.5, Cul, 0, 0 '1
                  AntiAlias picDATA(), iix, iy2 + 0.5, Cul, 0, 0 '1
               End If
            End If
         Next iix
      End If
      
      ' Square ends move out
      ix1 = ix1 - kxstep
      iy1 = iy1 - kystep
      ix2 = ix2 + kxstep
      iy2 = iy2 + kystep

      ' Square ends move in
'      ix1 = ix1 + kxstep
'      iy1 = iy1 + kystep
'      ix2 = ix2 - kxstep
'      iy2 = iy2 - kystep
   Next n
End Sub



Public Sub BresBoxRounded(ByVal ix1 As Single, ByVal iy1 As Single, ByVal ix2 As Single, ByVal iy2 As Single, _
   Cul As Long, Optional ND As Long = 1)
               
               BresBox ix1, iy1 + 1, ix2, iy2 + 1, Cul, pxsvORG
               If (PixelSize And 1) = 1 Then ' ODD
                  DrawDot ix1, iy1, Cul
                  DrawDot ix2, iy1, Cul
                  DrawDot ix2, iy2, Cul
                  DrawDot ix1, iy2, Cul
               Else ' EVEN
                  DrawDot ix1 + 1, iy1 + 2, Cul
                  DrawDot ix2, iy1 + 2, Cul
                  DrawDot ix2, iy2, Cul
                  DrawDot ix1 + 1, iy2, Cul
               End If

End Sub


Public Sub BresLine(ByVal ix1 As Long, ByVal iy1 As Long, ByVal ix2 As Long, ByVal iy2 As Long, _
   ByVal r As Byte, g As Byte, B As Byte, Optional ND As Long = 0, Optional Convert As Long = 0)
   ' Used for drawing lines into an array:-
   ' All TOOLS with non-AA lines
   ' Adder lines (hexagon, streaks etc)
   ' jigsaw pattern
   
' BresLine  picDATA(),ix1,iy1,ix2,iy2,R,G,B,ND
'** Public picDATA()
'** Public LOX,HIX,LOY,HIY
'** BASIC Bresenham Line for drawing into the picDATA() byte array
'** ND 0  If ND > 0 then add a pixel to x or y depending on slope (Used by Tubulars)
'** Plus clipping on LOX-HIX, LOY-HIY

Dim iix As Long, iiy As Long
Dim idx As Long, idy As Long
Dim jkstep As Long
Dim incx As Long
Dim id As Long
Dim ainc As Long, binc As Long
Dim jj As Long, kk As Long

If Convert > 0 Then ' Convert ixy12 to pData coords

   ix1 = ix1 + xlo
   iy1 = Form1.picDRAW.Height - iy1 + ylo
   ix2 = ix2 + xlo
   iy2 = Form1.picDRAW.Height - iy2 + ylo
   
End If

   
   
   ' Reject lines outside picDATA() or Selection

SetRect REC, 0, 0, FullW - 1, FullH - 1
      
      idx = Abs(ix2 - ix1)
      idy = Abs(iy2 - iy1)
      jkstep = 1
      incx = 1
      If idx < idy Then   '-- Steep slope
         
         If iy1 > iy2 Then jkstep = -1
         If ix2 < ix1 Then incx = -1
         id = 2 * idx - idy
         ainc = 2 * (idx - idy)   '-ve
         binc = 2 * idx
         jj = iy1: kk = iy2: iix = ix1
         For iiy = jj To kk Step jkstep
            If (iix >= LOX And iix <= HIX) And (iiy >= LOY And iiy <= HIY) Then
               
               If PtInRect(REC, iix, iiy) <> 0 Then
                  picDATA(0, iix, iiy) = B
                  picDATA(1, iix, iiy) = g
                  picDATA(2, iix, iiy) = r
               End If
            
            End If
            
            If ND > 0 Then
               If (iix + 1 >= LOX And iix + 1 <= HIX) And (iiy >= LOY And iiy <= HIY) Then
                  
                  If PtInRect(REC, iix + 1, iiy) <> 0 Then
                     picDATA(0, iix + 1, iiy) = B
                     picDATA(1, iix + 1, iiy) = g
                     picDATA(2, iix + 1, iiy) = r
                  End If
                  
               End If
            End If
            
            If id > 0 Then
               id = id + ainc
               iix = iix + incx
            Else
               id = id + binc
            End If
         Next iiy
      
      Else                'idx >= idy -- Shallow slope. NB ix iy switched
         
         If ix1 > ix2 Then jkstep = -1
         If iy2 < iy1 Then incx = -1
         id = 2 * idy - idx
         ainc = 2 * (idy - idx)   '-ve
         binc = 2 * idy
         jj = ix1: kk = ix2: iix = iy1
      
         For iiy = jj To kk Step jkstep
            ' Reject any point outside picData()
            ' NB switch in x,y
            If (iiy >= LOX And iiy <= HIX) And (iix >= LOY And iix <= HIY) Then
               
               If PtInRect(REC, iiy, iix) <> 0 Then
                  picDATA(0, iiy, iix) = B
                  picDATA(1, iiy, iix) = g
                  picDATA(2, iiy, iix) = r
               End If
               
               If ND > 0 Then
                  
                  If (iiy + 1 >= LOX And iiy + 1 <= HIX) And (iix >= LOY And iix <= HIY) Then
                     
                     If PtInRect(REC, iiy + 1, iix) <> 0 Then
                        picDATA(0, iiy + 1, iix) = B
                        picDATA(1, iiy + 1, iix) = g
                        picDATA(2, iiy + 1, iix) = r
                     End If
                     
                  End If
                  
                  If idx = idy Then ' 45 degrees
                     If (iix + 1 >= LOY And iix + 1) <= HIY And (iiy >= LOX And iiy <= HIX) Then
                        
                        If PtInRect(REC, iiy, iix + 1) <> 0 Then
                           picDATA(0, iiy, iix + 1) = B
                           picDATA(1, iiy, iix + 1) = g
                           picDATA(2, iiy, iix + 1) = r
                        End If
                        
                     End If
                  End If
               
               End If
            
            End If
            
            
            If id > 0 Then
               id = id + ainc
               iix = iix + incx
            Else
               id = id + binc
            End If
         Next iiy
      
      End If
   
End Sub

Public Sub BresLineCALC(ByVal ix1 As Long, ByVal iy1 As Long, ByVal ix2 As Long, ByVal iy2 As Long, _
   ByVal r As Byte, g As Byte, B As Byte, Optional ND As Long = 0)
   
' Called when  aSelectAccepted = True
' With Filters (Tilted Pixels) will come in with
' ix1,ix2=0 to FullW-1:  i1y,iy2=0 to FullH-1
   
   ' Used for drawing lines into an array:-
   ' Adder lines (hexagon, streaks etc)
   ' jigsaw pattern
   
' BresLine ix1,iy1,ix2,iy2,R,G,B,ND
'** Public picDATA()
'** Public LOX,HIX,LOY,HIY
'** BASIC Bresenham Line for drawing into a 2D Public
'** ND 0,1,2   1x1 2x2, 4x4 dots  NOT USED HERE!
'** Plus clipping on LOX-HIX, LOY-HIY

'NB FOR     If aSelectAccepted Then
Dim ixx As Long, iyy As Long

Dim iix As Long, iiy As Long
Dim idx As Long, idy As Long
Dim jkstep As Long
Dim incx As Long
Dim id As Long
Dim ainc As Long, binc As Long
Dim jj As Long, kk As Long

   ' Reject lines outside picDATA() or Selection
'Private REC As RECT
SetRect REC, 0, 0, FullW - 1, FullH - 1
'If PtInRect(REC, XX, YY) <> 0 Then

      
      idx = Abs(ix2 - ix1)
      idy = Abs(iy2 - iy1)
      jkstep = 1
      incx = 1
      If idx <= idy Then   '-- Steep slope
         
         If iy1 > iy2 Then jkstep = -1
         If ix2 < ix1 Then incx = -1
         id = 2 * idx - idy
         ainc = 2 * (idx - idy)   '-ve
         binc = 2 * idx
         jj = iy1
         kk = iy2
         iix = ix1
         For iiy = jj To kk Step jkstep
            If (iix >= LOX And iix <= HIX) And (iiy >= LOY And iiy <= HIY) Then
                  If Not aExternal Then   ' Internal
                     If MaskArray(iix - LOX, iiy - LOY) = 0 Then
                        picDATA(0, iix, iiy) = B
                        picDATA(1, iix, iiy) = g
                        picDATA(2, iix, iiy) = r
                     End If
                  Else  ' External
                     If MaskArray(iix - LOX, iiy - LOY) <> 0 Then
                        
                        If PtInRect(REC, iix, iiy) <> 0 Then
                           picDATA(0, iix, iiy) = B
                           picDATA(1, iix, iiy) = g
                           picDATA(2, iix, iiy) = r
                        End If
                     
                     End If
                  End If
            
            Else
               If aExternal Then
                  
                  If PtInRect(REC, iix, iiy) <> 0 Then
                     picDATA(0, iix, iiy) = B
                     picDATA(1, iix, iiy) = g
                     picDATA(2, iix, iiy) = r
                  End If
               
               End If
            End If
            
            If id > 0 Then
               id = id + ainc
               iix = iix + incx
            Else
               id = id + binc
            End If
         Next iiy
      
      Else                '-- Shallow slope
         
         If ix1 > ix2 Then jkstep = -1
         If iy2 < iy1 Then incx = -1
         id = 2 * idy - idx
         ainc = 2 * (idy - idx)   '-ve
         binc = 2 * idy
         jj = ix1
         kk = ix2
         iix = iy1
         For iiy = jj To kk Step jkstep
            If (iiy >= LOX And iiy <= HIX) And (iix >= LOY And iix <= HIY) Then
               'ixx = iix - LOY
               'iyy = iiy - LOX
               If Not aExternal Then   ' Internal
                  If MaskArray(iiy - LOX, iix - LOY) = 0 Then
                     picDATA(0, iiy, iix) = B
                     picDATA(1, iiy, iix) = g
                     picDATA(2, iiy, iix) = r
                  End If
               Else  ' External
                  If MaskArray(iiy - LOX, iix - LOY) <> 0 Then
                     If PtInRect(REC, iiy, iix) <> 0 Then
                        picDATA(0, iiy, iix) = B
                        picDATA(1, iiy, iix) = g
                        picDATA(2, iiy, iix) = r
                        End If
                  End If
               End If
            
            Else
               If aExternal Then
                  If PtInRect(REC, iiy, iix) <> 0 Then
                     picDATA(0, iiy, iix) = B
                     picDATA(1, iiy, iix) = g
                     picDATA(2, iiy, iix) = r
                  End If
               End If
            End If
            
            If id > 0 Then
               id = id + ainc
               iix = iix + incx
            Else
               id = id + binc
            End If
         Next iiy
      
      End If
End Sub

Public Sub BresEllipse(ByVal xc As Long, ByVal yc As Long, _
                    ByVal radx As Long, ByVal rady As Long, _
                    Cul As Long, _
                    Optional Fill As Long = 0, _
                    Optional ND As Long = 0, _
                    Optional Convert As Long = 0)
                    
' A Fast Bresenham Type Algorithm For Drawing Ellipses
' by John Kennedy. Modified by RR to plot in pData()

' Fill > 0 use Bresline to fill
' ND > 0 extra pixel plot 1,2 or 3 for Tubular center gradient inside point
' Convert > 0 Convert to pData coords

Dim r As RECT

Dim x As Long, y As Long
Dim XChange As Long, YChange As Long
Dim EllipseError As Long
Dim TwoASquare As Long, TwoBSquare As Long
Dim StoppingX As Long, StoppingY As Long
Dim Red As Byte, Green As Byte, Blue As Byte

Dim Offset As Long

Dim i As Long, j As Long
Dim XX As Long, YY As Long
Dim ixx As Long, iyy As Long
   
   
If Convert > 0 Then ' Convert xyc to pData coords

   xc = xc + xlo
   yc = Form1.picDRAW.Height - yc + ylo
   
End If
   
   TwoASquare = 2 * (radx * radx)
   TwoBSquare = 2 * (rady * rady)
   x = radx
   y = 0
   
   XChange = rady * rady * (1 - (2 * radx))
   YChange = radx * radx
   EllipseError = 0
   StoppingX = TwoBSquare * radx
   StoppingY = 0

   If StoppingX = 0 Then Exit Sub
   
   
   LngToRGB Cul, Red, Green, Blue
   SetRect r, 0, 0, FullW - 1, FullH - 1
   

   Do While StoppingX >= StoppingY  ' 1st set of points, y' > -1

' BresLine(ByVal ix1 As Long, ByVal iy1 As Long, ByVal ix2 As Long, ByVal iy2 As Long, _
'   ByVal R As Byte, g As Byte, B As Byte, Optional ND As Long = 0, Optional Convert As Long = 0)
      
      
      If Fill <> 0 Then   ' NB BresLine checks pData() limits
         'BresLine xc - x, yc + y, xc + x, yc + y, Red, Green, Blue
         'BresLine xc - x, yc - y, xc + x, yc - y, Red, Green, Blue
         If aSelectAccepted Then
            BresLineCALC xc - x, yc + y, xc + x, yc + y, Red, Green, Blue
            BresLineCALC xc - x, yc - y, xc + x, yc - y, Red, Green, Blue
         Else
            BresLine xc - x, yc + y, xc + x, yc + y, Red, Green, Blue
            BresLine xc - x, yc - y, xc + x, yc - y, Red, Green, Blue
         End If
      Else  ' Open Ellipses
         For i = -1 To 1 Step 2
         For j = -1 To 1 Step 2
            XX = xc + i * x: YY = yc + j * y
            
            'If XX >= LOX And XX <= HIX Then
            'If YY >= LOY And YY <= HIY Then
            
'   SetRect r, 0, 0, FullW - 1, FullH - 1
               
               
               If PtInRect(r, XX, YY) <> 0 Then ' Quad1
                  If aSelectAccepted Then
                     If (XX >= LOX And XX <= HIX) And (YY >= LOY And YY <= HIY) Then
                        If Not aExternal Then
                           If MaskArray(XX - LOX, YY - LOY) = 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        Else  ' External
                           If MaskArray(XX - LOX, YY - LOY) <> 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        End If
                     Else
                        If aExternal Then BresEllipseCALC XX, YY, Red, Green, Blue
                     End If
                  Else
                     BresEllipseCALC XX, YY, Red, Green, Blue
                  End If
               End If
            
            'End If
            'End If
         
         Next j
         Next i
         If ND > 0 Then    ' To avoid gaps
            For Offset = 1 To ND
               For i = -1 To 1 Step 2
               For j = -1 To 1 Step 2
                  XX = xc + i * x - Offset * i: YY = yc + j * y
                  

               If PtInRect(r, XX, YY) <> 0 Then ' Quad1
                  If aSelectAccepted Then
                     If (XX >= LOX And XX <= HIX) And (YY >= LOY And YY <= HIY) Then
                        If Not aExternal Then
                           If MaskArray(XX - LOX, YY - LOY) = 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        Else  ' External
                           If MaskArray(XX - LOX, YY - LOY) <> 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        End If
                     Else
                        If aExternal Then BresEllipseCALC XX, YY, Red, Green, Blue
                     End If
                  Else
                     BresEllipseCALC XX, YY, Red, Green, Blue
                  End If
               End If

'                  If XX >= LOX And XX <= HIX Then
'                  If YY >= LOY And YY <= HIY Then
'
'                     If PtInRect(r, XX, YY) <> 0 Then ' Quad1
'                        If aSelectAccepted Then
'                           If MaskArray(XX - LOX, YY - LOY) = 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
'                        Else
'                           BresEllipseCALC XX, YY, Red, Green, Blue
'                        End If
'
'                     End If
'
'                  End If
'                  End If
               
               Next j
               Next i
            Next Offset
         End If
      End If

      y = y + 1
      StoppingY = StoppingY + TwoASquare
      EllipseError = EllipseError + YChange
      YChange = YChange + TwoASquare

      If (2 * EllipseError) + XChange > 0 Then
         x = x - 1
         StoppingX = StoppingX - TwoBSquare
         EllipseError = EllipseError + XChange
         XChange = XChange + TwoBSquare
      End If
   Loop
   
'Exit Sub
   
   ' 2nd set of points
   x = 0
   y = rady
   
   XChange = rady * rady
   YChange = radx * radx * (1 - (2 * rady))
   EllipseError = 0
   StoppingX = 0
   StoppingY = TwoASquare * rady
   
   Do While StoppingX <= StoppingY     'do {2nd set of points, y' < -1}

      If Fill <> 0 Then  ' NB BresLine checks pData() limits
         If aSelectAccepted Then
            BresLineCALC xc - x, yc + y, xc + x, yc + y, Red, Green, Blue
            BresLineCALC xc - x, yc - y, xc + x, yc - y, Red, Green, Blue
         Else
            BresLine xc - x, yc + y, xc + x, yc + y, Red, Green, Blue
            BresLine xc - x, yc - y, xc + x, yc - y, Red, Green, Blue
         End If
      Else
         
         For i = -1 To 1 Step 2
         For j = -1 To 1 Step 2
            XX = xc + i * x: YY = yc + j * y

               If PtInRect(r, XX, YY) <> 0 Then ' Quad1
                  If aSelectAccepted Then
                     If (XX >= LOX And XX <= HIX) And (YY >= LOY And YY <= HIY) Then
                        If Not aExternal Then
                           If MaskArray(XX - LOX, YY - LOY) = 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        Else  ' External
                           If MaskArray(XX - LOX, YY - LOY) <> 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        End If
                     Else
                        If aExternal Then BresEllipseCALC XX, YY, Red, Green, Blue
                     End If
                  Else
                     BresEllipseCALC XX, YY, Red, Green, Blue
                  End If
               End If

'            If XX >= LOX And XX <= HIX Then
'            If YY >= LOY And YY <= HIY Then
'                  If PtInRect(r, XX, YY) <> 0 Then
'
'                     If aSelectAccepted Then
'                        If MaskArray(XX - LOX, YY - LOY) = 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
'                     Else
'                        BresEllipseCALC XX, YY, Red, Green, Blue
'                     End If
'
'                  End If
'
'            End If
'            End If
         
         Next j
         Next i
         If ND > 0 Then    ' To avoid gaps
            For Offset = 1 To ND
               For i = -1 To 1 Step 2
               For j = -1 To 1 Step 2
                  XX = xc + i * x: YY = yc + j * y - Offset * j
                  

               If PtInRect(r, XX, YY) <> 0 Then ' Quad1
                  If aSelectAccepted Then
                     If (XX >= LOX And XX <= HIX) And (YY >= LOY And YY <= HIY) Then
                        If Not aExternal Then
                           If MaskArray(XX - LOX, YY - LOY) = 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        Else  ' External
                           If MaskArray(XX - LOX, YY - LOY) <> 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
                        End If
                     Else
                        If aExternal Then BresEllipseCALC XX, YY, Red, Green, Blue
                     End If
                  Else
                     BresEllipseCALC XX, YY, Red, Green, Blue
                  End If
               End If

'                  If XX >= LOX And XX <= HIX Then
'                  If YY >= LOY And YY <= HIY Then
'                  If PtInRect(r, XX, YY) <> 0 Then ' Quad1
'
'                     If aSelectAccepted Then
'                        If MaskArray(XX - LOX, YY - LOY) = 0 Then BresEllipseCALC XX, YY, Red, Green, Blue
'                     Else
'                        BresEllipseCALC XX, YY, Red, Green, Blue
'                     End If
'
'                  End If
'
'                  End If
'                  End If
               
               
               Next j
               Next i
            Next Offset
         End If
      End If

      x = x + 1
      StoppingX = StoppingX + TwoBSquare
      EllipseError = EllipseError + XChange
      XChange = XChange + TwoBSquare

      If (2 * EllipseError) + YChange > 0 Then
         y = y - 1
         StoppingY = StoppingY - TwoASquare
         EllipseError = EllipseError + YChange
         YChange = YChange + TwoASquare
      End If
   Loop

End Sub

Private Sub BresEllipseCALC(XX As Long, YY As Long, Red As Byte, Green As Byte, Blue As Byte)
   picDATA(0, XX, YY) = Blue
   picDATA(1, XX, YY) = Green
   picDATA(2, XX, YY) = Red
End Sub


'NOT USED
Public Static Function Round14( _
    ByVal dblNumber As Double, _
    Optional ByVal numDecimalPlaces As Long = 1) As Double
' by Donald, donald@xbeat.net, 20020419
' modification of Round10 inspired by Jost's Round13 (Variant = CDec!)
  Dim fInit As Boolean
  Dim numDecimalPlacesPrev As Long
  Dim vFac As Variant
  Dim dFacInv As Double
  
  ' calc factor once for this depth of rounding
  If Not fInit Or numDecimalPlacesPrev <> numDecimalPlaces Then
    'vFac = CDec(10 ^ numDecimalPlaces)
    'dFacInv = 10 ^ -numDecimalPlaces
    
    vFac = CDec(10)
    dFacInv = 0.1
    
    numDecimalPlacesPrev = numDecimalPlaces
    fInit = True
  End If
  
  On Error GoTo Err_Round14

  If dblNumber > 0 Then
    Round14 = Int(dblNumber * vFac + 0.5)
    Round14 = Round14 * dFacInv
  Else
    Round14 = -Int(-dblNumber * vFac + 0.5)
    Round14 = Round14 * dFacInv
  End If
  
  Exit Function
  
Err_Round14:
  Round14 = dblNumber
End Function

Public Sub GetLineCircPts(ixa As Single, iya As Single, ixb As Single, iyb As Single, _
                     xc As Single, yc As Single, Rad As Single, _
                     ix1 As Single, iy1 As Single, ix2 As Single, iy2 As Single, _
                     NegTest As Single)
' For along line gradient
' IN
' ixa,iya -> ixb,iyb  lines parallel to diameter
' xc,yc,Rad Circle centre and radius
' OUT
' ix1,iy1 and ix2,iy2 intersection points on circle
' NegTest to check positive square root

' Adapted from:-
' paulbourke.net and PSC CodeId=73873 (reexre, Roberto Mior)

' For intersection
Dim zm As Single, zc As Single
Dim A As Single, B As Single, c As Single


      NegTest = 0
      A = (ixb - ixa) ^ 2 + (iyb - iya) ^ 2
      If A = 0 Then Exit Sub

      B = 2 * ((ixb - ixa) * (ixa - xc) + (iyb - iya) * (iya - yc))
      
      c = xc ^ 2 + yc ^ 2 + ixa ^ 2 + iya ^ 2 _
          - 2 * (xc * ixa + yc * iya) - Rad ^ 2

      NegTest = B ^ 2 - 4 * A * c
      If NegTest > 0 Then
         zm = (-B + Sqr(B ^ 2 - 4 * A * c)) / (2 * A)
         ix1 = ixa + zm * (ixb - ixa)
         iy1 = iya + zm * (iyb - iya)
         zm = (-B - Sqr(B ^ 2 - 4 * A * c)) / (2 * A)
         ix2 = ixa + zm * (ixb - ixa)
         iy2 = iya + zm * (iyb - iya)
      End If
End Sub


