Older Version Newer Version

JanetTerra JanetTerra Jul 24, 2006


Source Code for Demo1.bas

Tom Nally - steelweaver52 steelweaver52





If you prefer, you may download the zipped file .

Return to Chapter 4: Wire 1.0 Released (Making Complex Objects With Wire).


Demo1.bas


Demo2.bas




Source Demo1.bas

'''''''''''''''''''''''''''''''''''''''''''
'  demo1.bas                              '
'                                         '
'  LBWF Library ("Wire") Version 1.0      '
'                                         '
'''''''''''''''''''''''''''''''''''''''''''
'                                         '
'  Tomas J. Nally                         '
'  steelweaver52@aol.com                  '
'                                         '
'''''''''''''''''''''''''''''''''''''''''''

 
 
gosub [Initialize.Liberty.BASIC.WireFrame.Library]
 
 
    NOMAINWIN
    WindowWidth = 420 : WindowHeight = 470
    UpperLeftX = INT((DisplayWidth-WindowWidth)/2)
    UpperLeftY = INT((DisplayHeight-WindowHeight)/2)
 
graphicbox  #main.wfscene, 20, 20, 360, 360
STATICTEXT  #main.stat01, "Feedback:", 20, 400, 80, 20
TEXTBOX     #main.feedback, 105, 395, 275, 25
 
 
 
Open "Wire 1.0 - demo1.bas" for Window as #main
    print #main, "trapclose [Quit.click]"
    print #main.wfscene, "down; fill White; flush"
    print #main.wfscene, "setfocus "
    print #main, "font ms_sans_serif 10"
 
 
    Message = SendFeedback("Testing feedback textbox")
 
 
    'Set the camera location...
    CamX = 250
    CamY = 200
    CamZ = 160
    AAA = FF.LBWF.CameraLocation(CamX, CamY, CamZ)
 
    'Set the viewing center...
    VCtrX = 0
    VCtrY = 0
    VCtrZ = 0
    AAA = FF.LBWF.ViewingCenter(VCtrX, VCtrY, VCtrZ)
 
    'Set the zoom factor...
    ZoomFac = 1.6
    AAA = FF.LBWF.ZoomFactor(ZoomFac)
 
    'Set the screen center to the center point of the graphicbox...
    ScreenCenterX = 180 : ScreenCenterY = 180
    AAA = FF.LBWF.ScreenCenter(ScreenCenterX, ScreenCenterY)
 
    'Set a background color for the graphicbox...
    AAA = FF.LBWF.BackGroundColor("white")
 
    'Show the axes...
    AAA = FF.LBWF.ShowAxes()
 
    'Create a cylinder object...
    'CylName$ = "cyl1"
    'radius = 20
    'numSides = 20
    'cylheight = 50
    'CylColor$ = "darkgreen"
    'AAA = FF.LBWF.CreateCylinder(CylName$, radius, numSides, cylheight, CylColor$)
    
    'Create a grid object...
    GridName$ = "grid1"
    NumUnitsXdirection = 15
    NumUnitsZdirection = 15
    UnitSize = 15
    GridColor$ = "lightgray"
    AAA = FF.LBWF.CreateGridObject(GridName$, NumUnitsXdirection, NumUnitsZdirection, UnitSize, GridColor$)
 
    'AAA = FF.LBWF.ClearGraphicScreen()
    'AAA = FF.LBWF.DrawAllObjects()

 
    'For the very first time, create a complex object
    'by reading data from a file...
    AAA = FF.LBWF.CreateComplexObject("Spacecraft1", "Spacecraft01.cplx", "darkblue")
 
    'Move the object in the negative x, and the positive z direction...
    AAA = FF.LBWF.TranslateObject("Spacecraft1", -70, 0, 70)
 
    'Load the same object again, and give it a dark red color...
    AAA = FF.LBWF.CreateComplexObject("Spacecraft2", "Spacecraft01.cplx", "darkred")
    AAA = FF.LBWF.TranslateObject("Spacecraft2", 20, 0, 40)
 
    'Rotate the dark blue ship about the y axis...
    AAA = FF.LBWF.RotateObjectAboutY("Spacecraft1", -180)
 
    'Create yet another ship, and give it a dark pink color...
    AAA = FF.LBWF.CreateComplexObject("Spacecraft3", "Spacecraft01.cplx", "darkpink")
    AAA = FF.LBWF.TranslateObject("Spacecraft3", 20, 0, -40)
 
    'Rotate the second ship about the object's local X-axis...
    AAA = FF.LBWF.RotateObjectAboutX("Spacecraft2", 90)
    AAA = FF.LBWF.RotateObjectAboutY("Spacecraft2", -90)
 
    'Create a complex object using the "Gem1" data...
    AAA = FF.LBWF.CreateComplexObject("gem1", "Gem1.cplx", "darkgreen")
    AAA = FF.LBWF.TranslateObject("gem1", -60, 0, -70)
 
    'Create a second object using the "Gem1" data...
    AAA = FF.LBWF.CreateComplexObject("gem2", "Gem1.cplx", "darkblue")
    AAA = FF.LBWF.TranslateObject("gem2", -120, 0, -30)
 
    'Rotate the first gem...
    AAA = FF.LBWF.RotateObjectAboutY("gem1", 45)
 
 
    'Clear the screen and draw all objects...
    AAA = FF.LBWF.ClearGraphicScreen()
    AAA = FF.LBWF.DrawAllObjects()
 
    'Retrieve the type of the first gem object...
    Message = SendFeedback("type of gem object...")
    AAA = FF.LBWF.PauseUsingTimer(1000)
    GemType$ = FF.LBWF.RequestObjectType$("gem1")
    Message = SendFeedback(GemType$)
 
    'set the drawing rule to xor
    print #main.wfscene, "rule xor"
    AAA = FF.LBWF.DrawObject("gem2") 'this makes the object disappear temporarily...
    
 
    for i = 1 to 72
        AAA = FF.LBWF.RotateObjectAboutY("gem2", 5)
        AAA = FF.LBWF.DrawObject("gem2") 'this makes the object reappear...
        AAA = FF.LBWF.PauseUsingTimer(100)
        AAA = FF.LBWF.DrawObject("gem2") 'this makes the object disappear...
        
    next i
 
    print #main.wfscene, "rule over"
    AAA = FF.LBWF.DrawObject("gem2")
 
    'Set the line thickness of gem1 to 2...
    AAA = FF.LBWF.ObjectSetLineThickness("gem1", 2)
    AAA = FF.LBWF.DrawObject("gem1")
 
    AAA = FF.LBWF.PauseUsingTimer(1000)
    AAA = FF.LBWF.PointCameraAtObject("Spacecraft3")
 
    'Clear the screen and draw all objects...
    ZoomFac = 5.0
    AAA = FF.LBWF.ZoomFactor(ZoomFac)
    AAA = FF.LBWF.ClearGraphicScreen()
    AAA = FF.LBWF.DrawAllObjects()
 
    'Undraw Spacecraft3
    print #main.wfscene, "rule xor" 
    AAA = FF.LBWF.PauseUsingTimer(1000)
    AAA = FF.LBWF.DrawObject("Spacecraft3")
 
    'Rotate Spacecraft3 about its Y axis...
    for i = 1 to 72
        AAA = FF.LBWF.RotateObjectAboutY("Spacecraft3", 5)
        AAA = FF.LBWF.DrawObject("Spacecraft3")
        AAA = FF.LBWF.PauseUsingTimer(70)
        AAA = FF.LBWF.DrawObject("Spacecraft3")
    next i
 
    print #main.wfscene, "rule over"
    AAA = FF.LBWF.DrawObject("Spacecraft3")
 
    'Undraw Spacecraft3
    print #main.wfscene, "rule xor" 
    AAA = FF.LBWF.PauseUsingTimer(1000)
    AAA = FF.LBWF.DrawObject("Spacecraft3")
 
    'Rotate Spacecraft3 about its X axis...
    for i = 1 to 72
        AAA = FF.LBWF.RotateObjectAboutX("Spacecraft3", 5)
        AAA = FF.LBWF.DrawObject("Spacecraft3")
        AAA = FF.LBWF.PauseUsingTimer(70)
        AAA = FF.LBWF.DrawObject("Spacecraft3")
    next i
 
    print #main.wfscene, "rule over"
    AAA = FF.LBWF.DrawObject("Spacecraft3")
 
 
 
    'Display the geometric center of the first ship...
    'Message = SendFeedback("Center of first ship...")
    'AAA = FF.LBWF.PauseUsingTimer(1000)
    'Center1$ = FF.LBWF.RequestObjectGeometricCenter$("TheShip")
    'Message = SendFeedback(Center1$)
    'AAA = FF.LBWF.PauseUsingTimer(1000)
    'Message = SendFeedback("Center of second ship...")
    'AAA = FF.LBWF.PauseUsingTimer(1000)
    'Center2$ = FF.LBWF.RequestObjectGeometricCenter$("Ship2")
    'Message = SendFeedback(Center2$)
    'AAA = FF.LBWF.PauseUsingTimer(1000)
    'Message = SendFeedback("Center of third ship...")
    'AAA = FF.LBWF.PauseUsingTimer(1000)
    'Center3$ = FF.LBWF.RequestObjectGeometricCenter$("Ship3")
    'Message = SendFeedback(Center3$)

    Wait
 
 
 
[loop]
    Wait
 
 
 
[Quit.click]
    close #main : END
    wait
 
'''''''''''
Function SendFeedback(Message$)
 
    print #main.feedback, Message$
    SendFeedback = 0
 
End Function
 
'''''''''''

 
 
'---Insert library below this line----

 
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'        Begin Liberty BASIC WireFrame Library             '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
'''''''''''''''''''''''''''''''''''''''''''''''''''
'List of Liberty BASIC Wire Frame Library Functions
'''''''''''''''''''''''''''''''''''''''''''''''''''
'
'function count = 53
'
'Function FF.LBWF.Camera()
'Function FF.LBWF.CameraLocation()
'Function FF.LBWF.ViewingCenter()
'Function FF.LBWF.ZoomFactor()
'Function FF.LBWF.ScreenCenter()
'Function FF.LBWF.PointCameraAtObject()
'Function FF.LBWF.BackGroundColor()
'Function FF.LBWF.ShowAxes()
'Function FF.LBWF.HideAxes()
'Function FF.LBWF.SetAxesProperties()
'
'Function FF.LBWF.CreateBox()
'Function FF.LBWF.CreateCylinder()
'Function FF.LBWF.CreatePyramid()
'Function FF.LBWF.CreateCone()
'Function FF.LBWF.CreatePolygon()
'Function FF.LBWF.CreateGridObject()
'Function FF.LBWF.CreateDome()
'Function FF.LBWF.CreateLine()
'Function FF.LBWF.CreateCyl2()
'Function FF.LBWF.CreateComplexObject()
'
'Function FF.LBWF.TranslateObject()
'Function FF.LBWF.HideObject()
'Function FF.LBWF.ShowObject()
'Function FF.LBWF.ObjectSetColor()
'Function FF.LBWF.ObjectSetLineThickness()
'Function FF.LBWF.MoveObjectAbsolute()
'Function FF.LBWF.RotateObjectAboutY()
'Function FF.LBWF.RotateObjectAboutX()
'Function FF.LBWF.RotateObjectAboutZ()
'
'Function FF.LBWF.HideObjectsOfType()
'Function FF.LBWF.ShowObjectsOfType()
'Function FF.LBWF.TranslateObjectsOfType()
'Function FF.LBWF.DrawObjectsOfType()
'Function FF.LBWF.ObjectAssignCustomType()
'
'
'Function FF.LBWF.HideAllObjects()
'Function FF.LBWF.ShowAllObjects()
'
'Function FF.LBWF.ClearGraphicScreen()
'Function FF.LBWF.DrawObject()
'Function FF.LBWF.DrawAllObjects()
'
'Function FF.LBWF.LBWFVersion$()
'Function FF.LBWF.About()
'Function FF.LBWF.PauseMilliseconds()
'Function FF.LBWF.PauseUsingTimer()
'Function FF.LBWF.ZeroAllData()
'
'Function FF.LBWF.RequestLibraryResources$()
'Function FF.LBWF.RequestRemainingResources$()
'Function FF.LBWF.RequestObjectGeometricCenter$()
'Function FF.LBWF.RequestObjectColor$()
'Function FF.LBWF.RequestObjectLineThickness()
'Function FF.LBWF.RequestObjectType$()
'Function FF.LBWF.RequestObjectExtents$()
'Function FF.LBWF.RequestObjectVisibleState()
'Function FF.LBWF.RequestObjectNameFromXY$()
'
'
'Function FF.LBWF.ATAN2()
'Function FF.LBWF.FindPerpendicularDistance$()
'

 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
[Initialize.Liberty.BASIC.WireFrame.Library]
 
dim LBWF.CamX(1)
dim LBWF.CamY(1)
dim LBWF.CamZ(1)
dim LBWF.VCtrX(1)
dim LBWF.VCtrY(1)
dim LBWF.VCtrZ(1)
dim LBWF.ZoomFac(1)
dim LBWF.BackGroundColor$(1)
dim LBWF.VersionNumber$(1)
dim LBWF.NodeResources(1)
dim LBWF.LineResources(1)
dim LBWF.ObjectResources(1)
 
LBWF.CamX(1) = 200
LBWF.CamY(1) = 200
LBWF.CamZ(1) = 200
LBWF.VCtrX(1) = 0
LBWF.VCtrY(1) = 0
LBWF.VCtrZ(1) = 0
LBWF.ZoomFac(1) = 1
LBWF.BackGroundColor$(1) = "white"
LBWF.VersionNumber$(1) = "0.6a"
 
LBWF.NodeResources(1) = 4000
LBWF.LineResources(1) = 4000
LBWF.ObjectResources(1) = 500
 
 
dim LBWF.ScrCenterX(1)
dim LBWF.ScrCenterY(1)
 
LBWF.ScrCenterX(1) = 180
LBWF.ScrCenterY(1) = 180
 
dim LBWF.NodeCount(1)
dim LBWF.LineCount(1)
dim LBWF.ObjectCount(1)
 
LBWF.NodeCount(1) = 0
LBWF.LineCount(1) = 0
LBWF.ObjectCount(1) = 0
 
 
dim LBWF.NodeWX(LBWF.NodeResources(1))
dim LBWF.NodeWY(LBWF.NodeResources(1))
dim LBWF.NodeWZ(LBWF.NodeResources(1))
 
dim LBWF.NodeSX(LBWF.NodeResources(1))
dim LBWF.NodeSY(LBWF.NodeResources(1))
 
dim LBWF.LineInode(LBWF.LineResources(1))
dim LBWF.LineJnode(LBWF.LineResources(1))
 
dim LBWF.ObjectName$(LBWF.ObjectResources(1))
dim LBWF.ObjectColor$(LBWF.ObjectResources(1))
dim LBWF.ObjectFirstNode(LBWF.ObjectResources(1))
dim LBWF.ObjectLastNode(LBWF.ObjectResources(1))
 
dim LBWF.ObjectFirstLine(LBWF.ObjectResources(1))
dim LBWF.ObjectLastLine(LBWF.ObjectResources(1))
 
dim LBWF.ObjectVisible(LBWF.ObjectResources(1))
dim LBWF.ObjectLineThickness(LBWF.ObjectResources(1))
 
dim LBWF.ObjectType$(LBWF.ObjectResources(1))
 
dim LBWF.ObjectCenterX(LBWF.ObjectResources(1))
dim LBWF.ObjectCenterY(LBWF.ObjectResources(1))
dim LBWF.ObjectCenterZ(LBWF.ObjectResources(1))
 
 
    'Information about the axes...
    Dim LBWF.AxesVisible(1)
    LBWF.AxesVisible(1) = 0   'Default state: axes are NOT visible

    Dim LBWF.AxesLength(1)
    LBWF.AxesLength(1) = 50   'The startup length of the axes are 30 units
    
    Dim LBWF.AxesLineThickness(1)
    LBWF.AxesLineThickness(1) = 2   'The startup thickness of the axes objects is 2 pixels

    Dim LBWF.XaxisColor$(1)
    Dim LBWF.YaxisColor$(1)
    Dim LBWF.ZaxisColor$(1)
 
    LBWF.XaxisColor$(1) = "blue"
    LBWF.YaxisColor$(1) = "red"
    LBWF.ZaxisColor$(1) = "darkgreen"
 
 
    Dim LBWF.AxesWorldX(4)
    Dim LBWF.AxesWorldY(4)
    Dim LBWF.AxesWorldZ(4)
 
    Dim LBWF.AxesScreenX(4)
    Dim LBWF.AxesScreenY(4) 
 
    LBWF.AxesWorldX(1) = 0  'These are the world coordinates of
    LBWF.AxesWorldY(1) = 0  'the origin point.
    LBWF.AxesWorldZ(1) = 0  '

    LBWF.AxesWorldX(2) = LBWF.AxesLength(1)  'These are the coordinates of the end
    LBWF.AxesWorldY(2) = 0                   'end point of the X-axis
    LBWF.AxesWorldZ(2) = 0                   '

    LBWF.AxesWorldX(3) = 0                   'These are the coordinates of the
    LBWF.AxesWorldY(3) = LBWF.AxesLength(1)  'endpoint of the Y-axis
    LBWF.AxesWorldZ(3) = 0
 
    LBWF.AxesWorldX(4) = 0                   'These are the coordinates of the
    LBWF.AxesWorldY(4) = 0                   'endpoint of the Z-axis
    LBWF.AxesWorldZ(4) = LBWF.AxesLength(1)  '

'Dimension the arrays for complex objects...

    Dim LBWF.ComplexTextLines$(1000)
 
    dim LBWF.ComplexNodeID(300)
    dim LBWF.ComplexNodeX(300)
    dim LBWF.ComplexNodeY(300)
    dim LBWF.ComplexNodeZ(300)
 
    dim LBWF.ComplexLineID(300)
    dim LBWF.ComplexLineInode(300)
    dim LBWF.ComplexLineJnode(300)
 
 
    Return
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectNameFromXY$(ScreenX, ScreenY, pixelLimit)
 
    'This function identifies the first non-hidden object that
    'contains a line that is located within pixelLimit of the 
    'screen coordinates ScreenX and ScreenY...

 
    FF.LBWF.RequestObjectNameFromXY$ = "null00"
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
 
        'Only evaluate the lines in this object if the visible state
        'of the object has been set to "visible"
        
        If (LBWF.ObjectVisible(i) = 1) then
 
            ObjectToCheck = i
            FirstLineOfObjectToCheck = LBWF.ObjectFirstLine(ObjectToCheck)
            LastLineOfObjectToCheck  = LBWF.ObjectLastLine(ObjectToCheck)
 
            For j = FirstLineOfObjectToCheck to LastLineOfObjectToCheck
 
                TheLine = j
                InodeOfTheLine = LBWF.LineInode(TheLine)
                JnodeOfTheLine = LBWF.LineJnode(TheLine)
                xa = LBWF.NodeSX(InodeOfTheLine)
                ya = LBWF.NodeSY(InodeOfTheLine)
                xb = LBWF.NodeSX(JnodeOfTheLine)
                yb = LBWF.NodeSY(JnodeOfTheLine)
                xc = ScreenX
                yc = ScreenY
 
                Distance$ = FF.LBWF.FindPerpendicularDistance$(xa, ya, xb, yb, xc, yc)
                DistanceComponent    = val(word$(Distance$, 1))
                EvaluationComponent$ = word$(Distance$, 2)
 
                If ((DistanceComponent <= pixelLimit) and (EvaluationComponent$ = "yes")) then 
                    FF.LBWF.RequestObjectNameFromXY$ = LBWF.ObjectName$(i)
                    j = LastLineOfObjectToCheck
                    i = OC
                end if
 
            next j
 
 
        end if
 
    next i
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'LBWF.NodeSX()
'LBWF.NodeSY()

 
'LBWF.LineInode()
'LBWF.LineJnode()

'LBWF.ObjectCount(1) = 0
'LBWF.ObjectVisible(i)
'LBWF.ObjectFirstLine()
'LBWF.ObjectLastLine()

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreateComplexObject(ObjectName$, FileName$, ObjectColor$)
 
    'Read the complex object text file into an array...

    LineCount = 0
 
    open FileName$ for input as #cplx
 
    While (eof(#cplx) <> -1)
        LineCount = LineCount + 1
        Line input #cplx, TheLine$
        LBWF.ComplexTextLines$(LineCount) = TheLine$
    Wend
 
    close #cplx
 
 
    'Parse all of the text data lines into node data and
    'line data of the complex object...

    ComplexNodeCount = 0
    ComplexLineCount = 0
 
    For i = 1 to LineCount
 
    if (lower$(word$(LBWF.ComplexTextLines$(i), 1)) = "node") then
        ComplexNodeCount = ComplexNodeCount + 1
        LBWF.ComplexNodeID(ComplexNodeCount) = val(word$(LBWF.ComplexTextLines$(i), 2))
        LBWF.ComplexNodeX(LBWF.ComplexNodeID(ComplexNodeCount)) = val(word$(LBWF.ComplexTextLines$(i), 3))
        LBWF.ComplexNodeY(LBWF.ComplexNodeID(ComplexNodeCount)) = val(word$(LBWF.ComplexTextLines$(i), 4))
        LBWF.ComplexNodeZ(LBWF.ComplexNodeID(ComplexNodeCount)) = val(word$(LBWF.ComplexTextLines$(i), 5))
    end if
 
    if (lower$(word$(LBWF.ComplexTextLines$(i), 1)) = "line") then
        ComplexLineCount = ComplexLineCount + 1
        LBWF.ComplexLineID(ComplexLineCount) = val(word$(LBWF.ComplexTextLines$(i), 2))
        LBWF.ComplexLineInode(LBWF.ComplexLineID(ComplexLineCount)) = val(word$(LBWF.ComplexTextLines$(i), 3))
        LBWF.ComplexLineJnode(LBWF.ComplexLineID(ComplexLineCount)) = val(word$(LBWF.ComplexTextLines$(i), 4))
    end if
 
    next i
 
    'Integrate the data for the complex object into the database for
    'all of the wireframe objects, starting with the nodes...
    
    NC = LBWF.NodeCount(1)
 
    for i = 1 to ComplexNodeCount
        LBWF.NodeWX(NC + i) = LBWF.ComplexNodeX(i)
        LBWF.NodeWY(NC + i) = LBWF.ComplexNodeY(i)
        LBWF.NodeWZ(NC + i) = LBWF.ComplexNodeZ(i)
    next i
 
    'Define the new lines for this complex object...
    
    LC = LBWF.LineCount(1)
 
    for i = 1 to ComplexLineCount
        LBWF.LineInode(LC + i) = NC + LBWF.ComplexLineInode(i)
        LBWF.LineJnode(LC + i) = NC + LBWF.ComplexLineJnode(i)
    next i
 
    'Define other properties for this complex object...
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = ObjectName$
    LBWF.ObjectColor$(OC + 1)    = ObjectColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + ComplexNodeCount)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + ComplexLineCount)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "complex"
 
    'Determine the geometric center of the complex object.
    'First, for all nodal coordinates, determine the min and
    'max values for the x-, y- and z-directions...
    
    minX = LBWF.ComplexNodeX(1) : maxX = LBWF.ComplexNodeX(1)
    minY = LBWF.ComplexNodeY(1) : maxY = LBWF.ComplexNodeY(1)
    minZ = LBWF.ComplexNodeZ(1) : maxZ = LBWF.ComplexNodeZ(1)
 
    for i = 2 to ComplexNodeCount
 
        if (LBWF.ComplexNodeX(i) < minX) then
            minX = LBWF.ComplexNodeX(i)
        end if
 
        if (LBWF.ComplexNodeX(i) > maxX) then
            maxX = LBWF.ComplexNodeX(i)
        end if
 
        if (LBWF.ComplexNodeY(i) < minY) then
            minY = LBWF.ComplexNodeY(i)
        end if
 
        if (LBWF.ComplexNodeY(i) > maxY) then
            maxY = LBWF.ComplexNodeY(i)
        end if
 
        if (LBWF.ComplexNodeZ(i) < minZ) then
            minZ = LBWF.ComplexNodeZ(i)
        end if
 
        if (LBWF.ComplexNodeZ(i) > maxZ) then
            maxZ = LBWF.ComplexNodeZ(i)
        end if
 
    next i
 
    'The center of the object is equal to the value that 
    'is midway between the min value and the max value...
    LBWF.ObjectCenterX(OC + 1) = (minX + maxX)/2
    LBWF.ObjectCenterY(OC + 1) = (minY + maxY)/2
    LBWF.ObjectCenterZ(OC + 1) = (minZ + maxZ)/2
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + ComplexNodeCount
    LBWF.LineCount(1)   = LBWF.LineCount(1) + ComplexLineCount
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
 
 
 
 
End Function
 
' LBWF.LineInode(LBWF.LineResources(1))
' LBWF.LineJnode(LBWF.LineResources(1))

 
 
' LBWF.NodeWX(i)
' LBWF.NodeWY(i)
' LBWF.NodeWZ(i)

 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.ZeroAllData()
 
LBWF.CamX(1) = 200
LBWF.CamY(1) = 200
LBWF.CamZ(1) = 200
LBWF.VCtrX(1) = 0
LBWF.VCtrY(1) = 0
LBWF.VCtrZ(1) = 0
LBWF.ZoomFac(1) = 1
LBWF.BackGroundColor$(1) = "white"
LBWF.VersionNumber$(1) = "0.6a"
 
LBWF.NodeResources(1) = 4000
LBWF.LineResources(1) = 4000
LBWF.ObjectResources(1) = 500
 
LBWF.ScrCenterX(1) = 180
LBWF.ScrCenterY(1) = 180
 
LBWF.NodeCount(1) = 0
LBWF.LineCount(1) = 0
LBWF.ObjectCount(1) = 0
 
LBWF.AxesVisible(1) = 0   'Default state: axes are NOT visible

LBWF.AxesLength(1) = 50   'The startup length of the axes are 30 units
    
LBWF.AxesLineThickness(1) = 2   'The startup thickness of the axes objects is 2 pixels

LBWF.XaxisColor$(1) = "blue"
LBWF.YaxisColor$(1) = "red"
LBWF.ZaxisColor$(1) = "darkgreen"
 
LBWF.AxesWorldX(1) = 0  'These are the world coordinates of
LBWF.AxesWorldY(1) = 0  'the origin point.
LBWF.AxesWorldZ(1) = 0  '

LBWF.AxesWorldX(2) = LBWF.AxesLength(1)  'These are the coordinates of the end
LBWF.AxesWorldY(2) = 0                   'end point of the X-axis
LBWF.AxesWorldZ(2) = 0                   '

LBWF.AxesWorldX(3) = 0                   'These are the coordinates of the
LBWF.AxesWorldY(3) = LBWF.AxesLength(1)  'endpoint of the Y-axis
LBWF.AxesWorldZ(3) = 0
 
LBWF.AxesWorldX(4) = 0                   'These are the coordinates of the
LBWF.AxesWorldY(4) = 0                   'endpoint of the Z-axis
LBWF.AxesWorldZ(4) = LBWF.AxesLength(1)  '

 
 
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ObjectAssignCustomType(ObjectName$, CustomType$)
 
    ObjectToType = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToType = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    LBWF.ObjectType$(ObjectToType) = CustomType$
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''    
Function FF.LBWF.HideObjectsOfType(ObjectType$)
 
    'In version 0.6 of the library, this function presumes
    'that the programmer has passed a legitimate type
    'as an argument in the function.
    
    'Examine the types of all current objects.
    'If an object's type matches the type identified
    'in the argument of the function, then set the visibility
    'of that object to "hidden"
    
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        if (LBWF.ObjectType$(i) = ObjectType$) then
            LBWF.ObjectVisible(i) = 0
        end if 
    next i
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowObjectsOfType(ObjectType$)
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        if (LBWF.ObjectType$(i) = ObjectType$) then
            LBWF.ObjectVisible(i) = 1
        end if 
    next i
 
End function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.TranslateObjectsOfType(ObjectType$, transX, transY, transZ)
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        if (LBWF.ObjectType$(i) = ObjectType$) then
 
            FirstNode = LBWF.ObjectFirstNode(i)
            LastNode  = LBWF.ObjectLastNode(i)
 
            for j = FirstNode to LastNode
                LBWF.NodeWX(j) = LBWF.NodeWX(j) + transX
                LBWF.NodeWY(j) = LBWF.NodeWY(j) + transY
                LBWF.NodeWZ(j) = LBWF.NodeWZ(j) + transZ
            next j
 
            LBWF.ObjectCenterX(i) = LBWF.ObjectCenterX(i) + transX
            LBWF.ObjectCenterY(i) = LBWF.ObjectCenterY(i) + transY
            LBWF.ObjectCenterZ(i) = LBWF.ObjectCenterZ(i) + transZ
 
        end if 
    next i
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'dim LBWF.ObjectCenterX(i)
'dim LBWF.ObjectCenterY(i)
'dim LBWF.ObjectCenterZ(i)

'dim LBWF.NodeWX(i)
'dim LBWF.NodeWY(i)
'dim LBWF.NodeWZ(i)

 
'dim LBWF.ObjectFirstNode(i)
'dim LBWF.ObjectLastNode(i)
'dim LBWF.ObjectVisible(LBWF.ObjectResources(1))
'dim LBWF.ObjectLineThickness(LBWF.ObjectResources(1))
'dim LBWF.ObjectType$(LBWF.ObjectResources(1))    
    
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateLine(LineName$, x1, y1, z1, x2, y2, z2, LineColor$)
 
    NC = LBWF.NodeCount(1)
    LC = LBWF.LineCount(1)
 
    'Identify the two new nodes...
    LBWF.NodeWX(NC + 1) = x1
    LBWF.NodeWY(NC + 1) = y1
    LBWF.NodeWZ(NC + 1) = z1
 
    LBWF.NodeWX(NC + 2) = x2
    LBWF.NodeWY(NC + 2) = y2
    LBWF.NodeWZ(NC + 2) = z2
 
    'Identify the one new line...
    LBWF.LineInode(LC + 1) = (NC + 1)
    LBWF.LineJnode(LC + 1) = (NC + 2)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = LineName$
    LBWF.ObjectColor$(OC + 1)        = LineColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + 2)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + 1)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "line"
    LBWF.ObjectCenterX(OC + 1)       = (x1 + x2)/2
    LBWF.ObjectCenterY(OC + 1)       = (y1 + y2)/2
    LBWF.ObjectCenterZ(OC + 1)       = (z1 + z2)/2
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 2
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 1
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateDome(DomeName$, radius, numSides, DomeColor$)
 
    'Define the new nodes for this dome...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    NNDN = 3*numSides + 1    'Number of new dome nodes
    NNDL = 6*numSides        'Number of new dome lines

    'Find the coordinates of all the nodes on the base
    'layer of the dome...
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    'Find the coordinates of all the nodes on the SECOND
    'layer of the dome.
    NC1 = NC + numSides
    for i = 1 to numSides
        LBWF.NodeWX(NC1 + i) = 0.866*radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC1 + i) = 0.5*radius
        LBWF.NodeWZ(NC1 + i) = 0.866*radius*sin((i-1)*wedgeAngle)
    next i
 
    'Find the coordinates of all the nodes on the THIRD
    'layer of the dome.
    NC2 = NC1 + numSides
    for i = 1 to numSides
        LBWF.NodeWX(NC2 + i) = 0.500*radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC2 + i) = 0.866*radius
        LBWF.NodeWZ(NC2 + i) = 0.500*radius*sin((i-1)*wedgeAngle)
    next i
 
    'Identify the coordinate of the top-most node of the dome...
    LBWF.NodeWX(NC + 3*numSides + 1) = 0
    LBWF.NodeWY(NC + 3*numSides + 1) = radius
    LBWF.NodeWZ(NC + 3*numSides + 1) = 0
 
    'Define the new lines for this dome...
    LC = LBWF.LineCount(1)
 
    'These are the lines for the base layer of the dome...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the lines which connect the SECOND
    'layer of nodes...
    
    LC1 = LC + numSides
    NC1 = NC + numSides
 
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC1 + i) = (NC1 + i)
        LBWF.LineJnode(LC1 + i) = (NC1 + i + 1)
    next i
 
    LBWF.LineInode(LC1 + numSides) = (NC1 + numSides)
    LBWF.LineJnode(LC1 + numSides) = (NC1 + 1)
 
    'These are the lines which connect the THIRD
    'layer of nodes...
    
    LC2 = LC1 + numSides
    NC2 = NC1 + numSides
 
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC2 + i) = (NC2 + i)
        LBWF.LineJnode(LC2 + i) = (NC2 + i + 1)
    next i
 
    LBWF.LineInode(LC2 + numSides) = (NC2 + numSides)
    LBWF.LineJnode(LC2 + numSides) = (NC2 + 1)
 
    'These are the lines which connect the BASE layer
    'of nodes to the SECOND layer of nodes...
    
    LC3 = LC2 + numSides
 
    for i = 1 to numSides
        LBWF.LineInode(LC3 + i) = (NC + i)
        LBWF.LineJnode(LC3 + i) = (NC1 + i)
    next i
 
    'These are the lines which connect the SECOND layer
    'of nodes to the THIRD layer of nodes...
    
    LC4 = LC3 + numSides
 
    for i = 1 to numSides
        LBWF.LineInode(LC4 + i) = (NC1 + i)
        LBWF.LineJnode(LC4 + i) = (NC2 + i)
    next i
 
    'These are the lines which connect the THIRD layer
    'of nodes to the TOP-MOST node...
    
    LC5 = LC4 + numSides
 
    for i = 1 to numSides
        LBWF.LineInode(LC5 + i) = (NC2 + i)
        LBWF.LineJnode(LC5 + i) = (NC + NNDN)   'NNDN is the last node of the dome...
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = DomeName$
    LBWF.ObjectColor$(OC + 1)        = DomeColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + NNDN)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + NNDL)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "dome"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = radius/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + NNDN
    LBWF.LineCount(1)   = LBWF.LineCount(1) + NNDL
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
end function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.PauseUsingTimer(DelayMS)
 
    Timer DelayMS, [End.Of.Delay]
    Wait
    [End.Of.Delay]
    Timer 0
 
End Function
 
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.PauseMilliseconds(DelayMS)
 
    StartingTimeMS = time$("ms")
 
    ElapsedTimeMS = 0
 
    While (ElapsedTimeMS <= DelayMS)
        'Keep checking the elapsed time until the 
        'elapsed time is greater than the delay time
        'as contained in the variable DelayMS
        CurrentTimeMS = time$("ms")
        ElapsedTimeMS = CurrentTimeMS - StartingTimeMS
    Wend
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.About()
 
    Notice "Liberty BASIC Wireframe Library          " + chr$(13) + _
           "                                         " + chr$(13) + _
           "Library Version " + LBWF.VersionNumber$(1) + chr$(13) + _
           "                                         " + chr$(13) + _
           "by Tomas J. Nally                        "
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.LBWFVersion$()
 
    FF.LBWF.LBWFVersion$ = LBWF.VersionNumber$(1)
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ObjectSetColor(ObjectName$, NewColor$)
 
    'Determine the object whose color will
    'change by comparing the name of the object
    'against a list of all object names...
    
    ObjectToChangeColor = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToChangeColor = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Now that the object has been identified,
    'change its color property...
    
    LBWF.ObjectColor$(ObjectToChangeColor) = NewColor$
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ObjectSetLineThickness(ObjectName$, LineThickness)
 
    'Determine the object whose line thickness will
    'change by comparing the name of the object
    'against a list of all object names...
    
    ObjectToChange = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToChange = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Now that the object has been identified,
    'change its line thickness property...
    
    LBWF.ObjectLineThickness(ObjectToChange) = LineThickness
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.SetAxesProperties(AxesLength, AxesThickness)
 
    LBWF.AxesLength(1) = AxesLength
    LBWF.AxesWorldX(2) = LBWF.AxesLength(1)
    LBWF.AxesWorldY(3) = LBWF.AxesLength(1)
    LBWF.AxesWorldZ(4) = LBWF.AxesLength(1)
 
    LBWF.AxesLineThickness(1) = AxesThickness
 
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowAxes()
 
    LBWF.AxesVisible(1) = 1
 
End function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.HideAxes()
 
    LBWF.AxesVisible(1) = 0
 
End function
 
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowObject(ObjectName$)
 
    'Determine the object to be hidden by comparing the name
    'argument against a list of object names...
    
    ObjectToShow = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToShow = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Set the visible property of that object to 1...
    LBWF.ObjectVisible(ObjectToShow) = 1
 
end Function
 
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.HideObject(ObjectName$)
 
    'Determine the object to be hidden by comparing the name
    'argument against a list of object names...
    
    ObjectToHide = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToHide = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Set the visible property of that object to zero...
    LBWF.ObjectVisible(ObjectToHide) = 0
 
end Function
 
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.PointCameraAtObject(ObjectName$)
 
    'Find the geometric center of the object identified
    'as the argument above...
    
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    ObjectCenterX = val(word$(ObjectCenter$, 1))
    ObjectCenterY = val(word$(ObjectCenter$, 2))
    ObjectCenterZ = val(word$(ObjectCenter$, 3))
 
    'Now, point the camera to the x, y and z coordinates
    'identified above...
    
    AAA = FF.LBWF.ViewingCenter(ObjectCenterX, ObjectCenterY, ObjectCenterZ)
 
End Function
 
 
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateGridObject(GridName$, NumUnitsXdirection, NumUnitsZdirection, UnitSize, GridColor$)
 
    NumGridNodes = 2*(NumUnitsXdirection + 1) + 2*(NumUnitsZdirection + 1)
    NumGridLines = (NumUnitsXdirection + 1) + (NumUnitsZdirection + 1)
 
    TotalGridLengthX = NumUnitsXdirection * UnitSize
    TotalGridWidthZ  = NumUnitsZdirection * UnitSize
 
    UpperLeftCornerX = (0 - TotalGridLengthX/2)
    UpperLeftCornerZ = (0 - TotalGridWidthZ/2)
 
    LowerRightCornerX = TotalGridLengthX/2
    LowerRightCornerZ = TotalGridWidthZ/2
 
    NC = LBWF.NodeCount(1)
    LC = LBWF.LineCount(1)
 
    'Define all of the nodes which connect the lines parallel to 
    'the z-axis...
    
    for i = 1 to (NumUnitsXdirection + 1)
        LBWF.NodeWX(NC + i) = UpperLeftCornerX + (i-1)*UnitSize
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = UpperLeftCornerZ
    next i
 
    Na = NC + NumUnitsXdirection + 1
 
    for i = 1 to (NumUnitsXdirection + 1)
        LBWF.NodeWX(Na + i) = UpperLeftCornerX + (i-1)*UnitSize
        LBWF.NodeWY(Na + i) = 0
        LBWF.NodeWZ(Na + i) = LowerRightCornerZ
    next i
 
    'Define all of the nodes which connect the lines parallel to
    'the x-axis...
    
    Nb = NC + 2*(NumUnitsXdirection + 1)
 
    for i = 1 to (NumUnitsZdirection + 1)
        LBWF.NodeWX(Nb + i) = UpperLeftCornerX
        LBWF.NodeWY(Nb + i) = 0
        LBWF.NodeWZ(Nb + i) = UpperLeftCornerZ + (i-1)*UnitSize
    next i
 
    Nd = NC + 2*(NumUnitsXdirection + 1) + (NumUnitsZdirection + 1)
 
    for i = 1 to (NumUnitsZdirection + 1)
        LBWF.NodeWX(Nd + i) = LowerRightCornerX
        LBWF.NodeWY(Nd + i) = 0
        LBWF.NodeWZ(Nd + i) = UpperLeftCornerZ + (i-1)*UnitSize
    next i
 
    'Define the i-nodes and j-nodes for the (NumUnitsXdirection + 1) lines
    'that run parallel to the z-axis...
    
    for i = 1 to (NumUnitsXdirection + 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + (NumUnitsXdirection + 1) + i)
    next i
 
    'Define the i-nodes and j-nodes for the (NumUnitsZdirection + 1) lines
    'that run parallel to the x-axis...

    LCa = LC + (NumUnitsXdirection + 1)
 
    for i = 1 to (NumUnitsZdirection + 1)
        LBWF.LineInode(LCa + i) = (NC + 2*(NumUnitsXdirection + 1) + i)
        LBWF.LineJnode(LCa + i) = LBWF.LineInode(LCa + i) + (NumUnitsZdirection + 1)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = GridName$
    LBWF.ObjectColor$(OC + 1)        = GridColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + NumGridNodes)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + NumGridLines)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "grid"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = 0
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + NumGridNodes
    LBWF.LineCount(1)   = LBWF.LineCount(1) + NumGridLines
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreateCone(ConeName$, radius, numSides, coneheight, ConeColor$)
 
    'Define the new nodes for this cone...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    LBWF.NodeWX(NC + numSides + 1) = 0
    LBWF.NodeWY(NC + numSides + 1) = coneheight
    LBWF.NodeWZ(NC + numSides + 1) = 0
 
 
    'Define the new lines for this cone...
    LC = LBWF.LineCount(1)
 
    'These are the new lines for the bottom face of the cone...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the lines for the sides of the cone which
    'go from the base up to the peak of the cone...
    
    for i = 1 to numSides
        LBWF.LineInode(LC + numSides + i) = (NC + i)
        LBWF.LineJnode(LC + numSides + i) = (NC + numSides + 1)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = ConeName$
    LBWF.ObjectColor$(OC + 1)        = ConeColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + numSides + 1)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + 2*numSides)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "cone"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = coneheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + numSides + 1
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 2*numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreatePyramid(pyrName$, xdim, zdim, pyrheight, pyrColor$)
 
    'Define the 5 new nodes for this pyramid...
    NC = LBWF.NodeCount(1)
 
    LBWF.NodeWX(NC + 1) = xdim/2      : LBWF.NodeWY(NC + 1) = 0 : LBWF.NodeWZ(NC + 1) = (-1)*zdim/2
    LBWF.NodeWX(NC + 2) = xdim/2      : LBWF.NodeWY(NC + 2) = 0 : LBWF.NodeWZ(NC + 2) = zdim/2
    LBWF.NodeWX(NC + 3) = (-1)*xdim/2 : LBWF.NodeWY(NC + 3) = 0 : LBWF.NodeWZ(NC + 3) = zdim/2
    LBWF.NodeWX(NC + 4) = (-1)*xdim/2 : LBWF.NodeWY(NC + 4) = 0 : LBWF.NodeWZ(NC + 4) = (-1)*zdim/2
 
    LBWF.NodeWX(NC + 5) = 0 
    LBWF.NodeWY(NC + 5) = pyrheight 
    LBWF.NodeWZ(NC + 5) = 0
 
    'Define the 8 new lines for this pyramid...
    LC = LBWF.LineCount(1)
 
    LBWF.LineInode(LC + 1) = (NC + 1) : LBWF.LineJnode(LC + 1) = (NC + 2)
    LBWF.LineInode(LC + 2) = (NC + 2) : LBWF.LineJnode(LC + 2) = (NC + 3)
    LBWF.LineInode(LC + 3) = (NC + 3) : LBWF.LineJnode(LC + 3) = (NC + 4)
    LBWF.LineInode(LC + 4) = (NC + 4) : LBWF.LineJnode(LC + 4) = (NC + 1)
 
    LBWF.LineInode(LC + 5) = (NC + 1) : LBWF.LineJnode(LC + 5) = (NC + 5)
    LBWF.LineInode(LC + 6) = (NC + 2) : LBWF.LineJnode(LC + 6) = (NC + 5)
    LBWF.LineInode(LC + 7) = (NC + 3) : LBWF.LineJnode(LC + 7) = (NC + 5)
    LBWF.LineInode(LC + 8) = (NC + 4) : LBWF.LineJnode(LC + 8) = (NC + 5)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = pyrName$
    LBWF.ObjectColor$(OC + 1)    = pyrColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 5)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 8)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "pyramid"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = pyrheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 5
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 8
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
end Function
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.TranslateObject(ObjectName$, transX, transY, transZ)
 
    'Determine the object to be translated by comparing the name
    'argument against a list of object names...
    
    ObjectToTranslate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToTranslate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FirstNodeToMove = LBWF.ObjectFirstNode(ObjectToTranslate)
    LastNodeToMove  = LBWF.ObjectLastNode(ObjectToTranslate)
 
    for i = FirstNodeToMove to LastNodeToMove
        LBWF.NodeWX(i) = LBWF.NodeWX(i) + transX
        LBWF.NodeWY(i) = LBWF.NodeWY(i) + transY
        LBWF.NodeWZ(i) = LBWF.NodeWZ(i) + transZ
    next i
 
    'As of Library Version 0.6, the array variables
    'which hold the values of the geometric center
    'of the object must be adjusted also

    LBWF.ObjectCenterX(ObjectToTranslate) = LBWF.ObjectCenterX(ObjectToTranslate) + transX
    LBWF.ObjectCenterY(ObjectToTranslate) = LBWF.ObjectCenterY(ObjectToTranslate) + transY
    LBWF.ObjectCenterZ(ObjectToTranslate) = LBWF.ObjectCenterZ(ObjectToTranslate) + transZ
 
 
end Function
 
 
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreatePolygon(PolyName$, radius, numSides, PolyColor$)
 
    'Define the new nodes for this polygon...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    'Define the lines for this polygon...
    LC = LBWF.LineCount(1)
 
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = PolyName$
    LBWF.ObjectColor$(OC + 1)    = PolyColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + numSides)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + numSides)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "polygon"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = 0
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + numSides
    LBWF.LineCount(1)   = LBWF.LineCount(1) + numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateCyl2(Cyl2Name$, radiusBottum, radiusTop, numSides, cyl2height, Cyl2Color$)
 
    'Define the new nodes for this cyl2...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radiusBottum*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radiusBottum*sin((i-1)*wedgeAngle)
    next i
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + numSides + i) = radiusTop*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + numSides + i) = cyl2height
        LBWF.NodeWZ(NC + numSides + i) = radiusTop*sin((i-1)*wedgeAngle)
    next i
 
    'Define the new lines for this cyl2...
    
    LC = LBWF.LineCount(1)
 
    'These are the new lines for the bottom face of the cyl2...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the new lines for the top face of the cyl2...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + numSides + i) = (NC + numSides + i)
        LBWF.LineJnode(LC + numSides + i) = (NC + numSides + i + 1)
    next i
 
    LBWF.LineInode(LC + 2*numSides) = (NC + 2*numSides)
    LBWF.LineJnode(LC + 2*numSides) = (NC + numSides + 1)
 
    'These are the side lines of the cyl2...
    
    for i = 1 to numSides
        LBWF.LineInode(LC + 2*numSides + i) = (NC + i)
        LBWF.LineJnode(LC + 2*numSides + i) = (NC + numSides + i)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = Cyl2Name$
    LBWF.ObjectColor$(OC + 1)    = Cyl2Color$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 2*numSides)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 3*numSides)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "cyl2"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = cyl2height/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 2*numSides
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 3*numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''

 
Function FF.LBWF.CreateCylinder(ObjectName$, radius, numSides, cylheight, ObjectColor$)
 
    'Define the new nodes for this cylinder...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + numSides + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + numSides + i) = cylheight
        LBWF.NodeWZ(NC + numSides + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    'Define the new lines for this cylinder...
    
    LC = LBWF.LineCount(1)
 
    'These are the new lines for the bottom face of the cylinder...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the new lines for the top face of the cylinder...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + numSides + i) = (NC + numSides + i)
        LBWF.LineJnode(LC + numSides + i) = (NC + numSides + i + 1)
    next i
 
    LBWF.LineInode(LC + 2*numSides) = (NC + 2*numSides)
    LBWF.LineJnode(LC + 2*numSides) = (NC + numSides + 1)
 
    'These are the side lines of the cylinder...
    
    for i = 1 to numSides
        LBWF.LineInode(LC + 2*numSides + i) = (NC + i)
        LBWF.LineJnode(LC + 2*numSides + i) = (NC + numSides + i)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = ObjectName$
    LBWF.ObjectColor$(OC + 1)    = ObjectColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 2*numSides)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 3*numSides)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "cylinder"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = cylheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 2*numSides
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 3*numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
end Function
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreateBox(ObjectName$, xdim, zdim, boxheight, ObjectColor$)
 
    'Define the 8 new nodes for this box...
    NC = LBWF.NodeCount(1)
    BH = boxheight
 
    LBWF.NodeWX(NC + 1) = xdim/2      : LBWF.NodeWY(NC + 1) = 0 : LBWF.NodeWZ(NC + 1) = (-1)*zdim/2
    LBWF.NodeWX(NC + 2) = xdim/2      : LBWF.NodeWY(NC + 2) = 0 : LBWF.NodeWZ(NC + 2) = zdim/2
    LBWF.NodeWX(NC + 3) = (-1)*xdim/2 : LBWF.NodeWY(NC + 3) = 0 : LBWF.NodeWZ(NC + 3) = zdim/2
    LBWF.NodeWX(NC + 4) = (-1)*xdim/2 : LBWF.NodeWY(NC + 4) = 0 : LBWF.NodeWZ(NC + 4) = (-1)*zdim/2
 
    LBWF.NodeWX(NC + 5) = xdim/2      : LBWF.NodeWY(NC + 5) = BH : LBWF.NodeWZ(NC + 5) = (-1)*zdim/2
    LBWF.NodeWX(NC + 6) = xdim/2      : LBWF.NodeWY(NC + 6) = BH : LBWF.NodeWZ(NC + 6) = zdim/2
    LBWF.NodeWX(NC + 7) = (-1)*xdim/2 : LBWF.NodeWY(NC + 7) = BH : LBWF.NodeWZ(NC + 7) = zdim/2
    LBWF.NodeWX(NC + 8) = (-1)*xdim/2 : LBWF.NodeWY(NC + 8) = BH : LBWF.NodeWZ(NC + 8) = (-1)*zdim/2
 
 
    'Define 12 new lines for this box...
    LC = LBWF.LineCount(1)
 
    LBWF.LineInode(LC + 1) = (NC + 1) : LBWF.LineJnode(LC + 1) = (NC + 2)
    LBWF.LineInode(LC + 2) = (NC + 2) : LBWF.LineJnode(LC + 2) = (NC + 3)
    LBWF.LineInode(LC + 3) = (NC + 3) : LBWF.LineJnode(LC + 3) = (NC + 4)
    LBWF.LineInode(LC + 4) = (NC + 4) : LBWF.LineJnode(LC + 4) = (NC + 1)
 
    LBWF.LineInode(LC + 5) = (NC + 1) : LBWF.LineJnode(LC + 5) = (NC + 5)
    LBWF.LineInode(LC + 6) = (NC + 2) : LBWF.LineJnode(LC + 6) = (NC + 6)
    LBWF.LineInode(LC + 7) = (NC + 3) : LBWF.LineJnode(LC + 7) = (NC + 7)
    LBWF.LineInode(LC + 8) = (NC + 4) : LBWF.LineJnode(LC + 8) = (NC + 8)
 
    LBWF.LineInode(LC + 9)  = (NC + 5) : LBWF.LineJnode(LC + 9)  = (NC + 6)
    LBWF.LineInode(LC + 10) = (NC + 6) : LBWF.LineJnode(LC + 10) = (NC + 7)
    LBWF.LineInode(LC + 11) = (NC + 7) : LBWF.LineJnode(LC + 11) = (NC + 8)
    LBWF.LineInode(LC + 12) = (NC + 8) : LBWF.LineJnode(LC + 12) = (NC + 5)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = ObjectName$
    LBWF.ObjectColor$(OC + 1)    = ObjectColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 8)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 12)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "box"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = boxheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 8
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 12
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
    FF.LBWF.CreateBox = 0
 
end function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CameraLocation(CamX, CamY, CamZ)
 
    LBWF.CamX(1) = CamX
    LBWF.CamY(1) = CamY
    LBWF.CamZ(1) = CamZ
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ViewingCenter(VCtrX, VCtrY, VCtrZ)
 
    LBWF.VCtrX(1) = VCtrX
    LBWF.VCtrY(1) = VCtrY
    LBWF.VCtrZ(1) = VCtrZ
 
End Function
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ZoomFactor(ZoomFac)
 
    LBWF.ZoomFac(1) = ZoomFac
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.Camera(CamX, CamY, CamZ, VCtrX, VCtrY, VCtrZ, ZoomFac)
 
    LBWF.CamX(1) = CamX
    LBWF.CamY(1) = CamY
    LBWF.CamZ(1) = CamZ
    LBWF.VCtrX(1) = VCtrX
    LBWF.VCtrY(1) = VCtrY
    LBWF.VCtrZ(1) = VCtrZ
    LBWF.ZoomFac(1) = ZoomFac
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ScreenCenter(ScrCenterX, ScrCenterY)
 
    LBWF.ScrCenterX(1) = ScrCenterX
    LBWF.ScrCenterY(1) = ScrCenterY
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.BackGroundColor(BGColor$)
 
    LBWF.BackGroundColor$(1) = BGColor$
 
end Function
 
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ClearGraphicScreen()
 
    print #main.wfscene, "cls"
    print #main.wfscene, "fill "; LBWF.BackGroundColor$(1)
 
end Function
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.DrawObjectsOfType(ObjectType$)
 
    OC = LBWF.ObjectCount(1)
 
    for q = 1 to OC
 
        if (LBWF.ObjectType$(q) = ObjectType$) then
 
            ObjectToDraw = q
 
            FirstNodeOfObject = LBWF.ObjectFirstNode(ObjectToDraw)
            LastNodeOfObject  = LBWF.ObjectLastNode(ObjectToDraw)
            FirstLineOfObject = LBWF.ObjectFirstLine(ObjectToDraw)
            LastLineOfObject  = LBWF.ObjectLastLine(ObjectToDraw)
 
            'The documentation for this elaborate procedure will
            'not be contained herein.  To see the documentation,
            'visit the function FF.LBWF.DrawAllObjects()

            Cam2CtrX = (LBWF.VCtrX(1) - LBWF.CamX(1))
            Cam2CtrY = (LBWF.VCtrY(1) - LBWF.CamY(1))
            Cam2CtrZ = (LBWF.VCtrZ(1) - LBWF.CamZ(1))
 
            LenCam2Ctr = sqr(Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2)
 
            virtualXi = (-1)*(Cam2CtrZ)
            virtualXj = 0
            virtualXk = Cam2CtrX
 
            LenVirtualX = sqr(virtualXi^2 + virtualXj^2 + virtualXk^2)
            virtualXi = virtualXi / LenVirtualX
            virtualXj = virtualXj / LenVirtualX
            virtualXk = virtualXk / LenVirtualX
 
            virtualYi = (-1)*(virtualXk * Cam2CtrY)
            virtualYj = (virtualXk * Cam2CtrX) - (virtualXi * Cam2CtrZ)
            virtualYk = (virtualXi * Cam2CtrY)
 
            LenVirtualY = sqr(virtualYi^2 + virtualYj^2 + virtualYk^2)
            virtualYi = virtualYi / LenVirtualY
            virtualYj = virtualYj / LenVirtualY
            virtualYk = virtualYk / LenVirtualY
 
            virtualXi = virtualXi / LenCam2Ctr
            virtualXj = virtualXj / LenCam2Ctr
            virtualXk = virtualXk / LenCam2Ctr
 
            virtualYi = virtualYi / LenCam2Ctr
            virtualYj = virtualYj / LenCam2Ctr
            virtualYk = virtualYk / LenCam2Ctr
 
            '''''''''''''''''''''''''''''''''''''''''''''''
            'FIND SCREEN COORDINATES OF OBJECT NODES
            '''''''''''''''''''''''''''''''''''''''''''''''
    
            for i = FirstNodeOfObject to LastNodeOfObject
 
                'Establish the vector components of the Camera-to-Node Vector
                Cam2NodeX = (LBWF.NodeWX(i) - LBWF.CamX(1))
                Cam2NodeY = (LBWF.NodeWY(i) - LBWF.CamY(1))
                Cam2NodeZ = (LBWF.NodeWZ(i) - LBWF.CamZ(1))
 
                numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
                denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
                t = (numerator / denominator)
 
                ipX = LBWF.CamX(1) + Cam2NodeX*t
                ipY = LBWF.CamY(1) + Cam2NodeY*t
                ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
                Ctr2ipX = (ipX - LBWF.VCtrX(1))
                Ctr2ipY = (ipY - LBWF.VCtrY(1))
                Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
                PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
                SCM = 500   'Note: SCM is an acronym for "Secondary Scale Multiplier".
                            '      This value was found by experimentation when it was
                            '      observed that the Scale factor by itself was
                            '      too small without a multiplier.

                LBWF.NodeSX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
                PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
                LBWF.NodeSY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
            next i
 
            'With the the screen coordinates of the nodes determined,
            'it is time to draw each line of the object...

                'Set the drawing color for the object...
                DrawingColor$ = LBWF.ObjectColor$(ObjectToDraw)
                print #main.wfscene, "color "; DrawingColor$
 
                'Set the line thickness for the object...
                LineThickness = LBWF.ObjectLineThickness(ObjectToDraw)
                print #main.wfscene, "size "; LineThickness
 
                for i = FirstLineOfObject to LastLineOfObject
                    x1 = LBWF.NodeSX(LBWF.LineInode(i))
                    y1 = LBWF.NodeSY(LBWF.LineInode(i))
                    x2 = LBWF.NodeSX(LBWF.LineJnode(i))
                    y2 = LBWF.NodeSY(LBWF.LineJnode(i))
 
                    print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
                next i
 
        end if
 
    next q
 
    'Reset the default line thickness back to 1...
    print #main.wfscene, "size 1" 
 
    'Set the default drawing color back to black...
    print #main.wfscene, "color black"
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.DrawObject(ObjectName$)
 
    ObjectToDraw = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToDraw = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FirstNodeOfObject = LBWF.ObjectFirstNode(ObjectToDraw)
    LastNodeOfObject  = LBWF.ObjectLastNode(ObjectToDraw)
    FirstLineOfObject = LBWF.ObjectFirstLine(ObjectToDraw)
    LastLineOfObject  = LBWF.ObjectLastLine(ObjectToDraw)
 
    'The documentation for this elaborate procedure will
    'not be contained herein.  To see the documentation,
    'visit the function FF.LBWF.DrawAllObjects()

    Cam2CtrX = (LBWF.VCtrX(1) - LBWF.CamX(1))
    Cam2CtrY = (LBWF.VCtrY(1) - LBWF.CamY(1))
    Cam2CtrZ = (LBWF.VCtrZ(1) - LBWF.CamZ(1))
 
    LenCam2Ctr = sqr(Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2)
 
    virtualXi = (-1)*(Cam2CtrZ)
    virtualXj = 0
    virtualXk = Cam2CtrX
 
    LenVirtualX = sqr(virtualXi^2 + virtualXj^2 + virtualXk^2)
    virtualXi = virtualXi / LenVirtualX
    virtualXj = virtualXj / LenVirtualX
    virtualXk = virtualXk / LenVirtualX
 
    virtualYi = (-1)*(virtualXk * Cam2CtrY)
    virtualYj = (virtualXk * Cam2CtrX) - (virtualXi * Cam2CtrZ)
    virtualYk = (virtualXi * Cam2CtrY)
 
    LenVirtualY = sqr(virtualYi^2 + virtualYj^2 + virtualYk^2)
    virtualYi = virtualYi / LenVirtualY
    virtualYj = virtualYj / LenVirtualY
    virtualYk = virtualYk / LenVirtualY
 
    virtualXi = virtualXi / LenCam2Ctr
    virtualXj = virtualXj / LenCam2Ctr
    virtualXk = virtualXk / LenCam2Ctr
 
    virtualYi = virtualYi / LenCam2Ctr
    virtualYj = virtualYj / LenCam2Ctr
    virtualYk = virtualYk / LenCam2Ctr
 
    '''''''''''''''''''''''''''''''''''''''''''''''
    'FIND SCREEN COORDINATES OF OBJECT NODES
    '''''''''''''''''''''''''''''''''''''''''''''''
    
    for i = FirstNodeOfObject to LastNodeOfObject
 
        'Establish the vector components of the Camera-to-Node Vector
        Cam2NodeX = (LBWF.NodeWX(i) - LBWF.CamX(1))
        Cam2NodeY = (LBWF.NodeWY(i) - LBWF.CamY(1))
        Cam2NodeZ = (LBWF.NodeWZ(i) - LBWF.CamZ(1))
 
        numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
        denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
        t = (numerator / denominator)
 
        ipX = LBWF.CamX(1) + Cam2NodeX*t
        ipY = LBWF.CamY(1) + Cam2NodeY*t
        ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
        Ctr2ipX = (ipX - LBWF.VCtrX(1))
        Ctr2ipY = (ipY - LBWF.VCtrY(1))
        Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
        PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
        SCM = 500   'Note: SCM is an acronym for "Secondary Scale Multiplier".
                    '      This value was found by experimentation when it was
                    '      observed that the Scale factor by itself was
                    '      too small without a multiplier.

        LBWF.NodeSX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
        PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
        LBWF.NodeSY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
    next i
 
    'With the the screen coordinates of the nodes determined,
    'it is time to draw each line of the object...

        'Set the drawing color for the object...
        DrawingColor$ = LBWF.ObjectColor$(ObjectToDraw)
        print #main.wfscene, "color "; DrawingColor$
 
        'Set the line thickness for the object...
        LineThickness = LBWF.ObjectLineThickness(ObjectToDraw)
        print #main.wfscene, "size "; LineThickness
 
        for i = FirstLineOfObject to LastLineOfObject
            x1 = LBWF.NodeSX(LBWF.LineInode(i))
            y1 = LBWF.NodeSY(LBWF.LineInode(i))
            x2 = LBWF.NodeSX(LBWF.LineJnode(i))
            y2 = LBWF.NodeSY(LBWF.LineJnode(i))
 
            print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
        next i
 
    'Reset the default line thickness back to 1...
    print #main.wfscene, "size 1" 
 
    'Set the default drawing color back to black...
    print #main.wfscene, "color black"
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.DrawAllObjects()
 
    'Find the camera-to-viewing-center vector...

    Cam2CtrX = (LBWF.VCtrX(1) - LBWF.CamX(1))
    Cam2CtrY = (LBWF.VCtrY(1) - LBWF.CamY(1))
    Cam2CtrZ = (LBWF.VCtrZ(1) - LBWF.CamZ(1))
 
    'Length of the camera-to-viewing-center vector...

    LenCam2Ctr = sqr(Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2)
 
    'The vector equation for the virtual image plane can be written
    'as follows:
    '
    'Cam2CtrX*(x - CtrX) + Cam2CtrY*(y - CtrY) + Cam2CtrZ*(z - CtrZ) = 0

    'Imagine a unit vector pointing in the -Y direction.  The
    'components of this vector are 0i -1j + 0k.  When we take
    'the cross product of this vector with the Camera-to-Center
    'vector, the result is the virtual x-axis vector imposed
    'upon the virtual image plane.  These are the vector
    'components of the virtual x-axis vector.

    virtualXi = (-1)*(Cam2CtrZ)
    virtualXj = 0
    virtualXk = Cam2CtrX
 
    'Find the length of this vector, then divide components
    'by this length.

    LenVirtualX = sqr(virtualXi^2 + virtualXj^2 + virtualXk^2)
    virtualXi = virtualXi / LenVirtualX
    virtualXj = virtualXj / LenVirtualX
    virtualXk = virtualXk / LenVirtualX
 
 
    'In order to find the virtual y-axis on the image plane,
    'we need to take the cross product of the virtual x-axis
    'vector with the Camera-to-Center Vector.  Given below is
    'the result of that cross product.

    virtualYi = (-1)*(virtualXk * Cam2CtrY)
    virtualYj = (virtualXk * Cam2CtrX) - (virtualXi * Cam2CtrZ)
    virtualYk = (virtualXi * Cam2CtrY)
 
    'Find the length of this vector, then divide the
    'components by this length

    LenVirtualY = sqr(virtualYi^2 + virtualYj^2 + virtualYk^2)
    virtualYi = virtualYi / LenVirtualY
    virtualYj = virtualYj / LenVirtualY
    virtualYk = virtualYk / LenVirtualY
 
    'Divide the unit virtual X-axis vector and the
    'virtual Y-axis vector by LenCam2Ctr.  This transformation
    'of these two vectors will allow the objects to get
    'smaller as the camera moves away from the viewing
    'center, or get larger as the camera moves toward
    'the viewing center.

    virtualXi = virtualXi / LenCam2Ctr
    virtualXj = virtualXj / LenCam2Ctr
    virtualXk = virtualXk / LenCam2Ctr
 
    virtualYi = virtualYi / LenCam2Ctr
    virtualYj = virtualYj / LenCam2Ctr
    virtualYk = virtualYk / LenCam2Ctr
 
    '''''''''''''''''''''''''''''''''''''''''''''''
    'OBJECT NODES *** OBJECT NODES *** OBJECT NODES
    '''''''''''''''''''''''''''''''''''''''''''''''
    'For each and every node in every object,
    'find the screen coordinates

    for i = 1 to LBWF.NodeCount(1)
 
        'Establish the vector components of the Camera-to-Node Vector
        Cam2NodeX = (LBWF.NodeWX(i) - LBWF.CamX(1))
        Cam2NodeY = (LBWF.NodeWY(i) - LBWF.CamY(1))
        Cam2NodeZ = (LBWF.NodeWZ(i) - LBWF.CamZ(1))
 
        'The parametric equations for the Camera-to-Node Vector
        'can be written as follows:
        '
        'x = CamX + Cam2NodeX*t
        'y = CamY + Cam2NodeY*t
        'z = CamZ + Cam2NodeZ*t
        '
        'Plug these three equations into the vector equation
        'for the virtual image plane...
        '
        'Cam2CtrX*(x - CtrX) + Cam2CtrY*(y - CtrY) + Cam2CtrZ*(z - CtrZ) = 0
        '
        '...and then solve for t

        numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
        denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
        t = (numerator / denominator)
 
        'Having solved for t, determine the point in space
        '(ipx, ipy, ipz) where 'the Camera-to-Node vector intersects
        'the virtual image plane.

        ipX = LBWF.CamX(1) + Cam2NodeX*t
        ipY = LBWF.CamY(1) + Cam2NodeY*t
        ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
        'Establish the vector components of the vector from the
        'center to (ipx, ipy, ipz).

        Ctr2ipX = (ipX - LBWF.VCtrX(1))
        Ctr2ipY = (ipY - LBWF.VCtrY(1))
        Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
        'The projection of this vector along the virtual X-axis
        'is the dot product of this vector with the unit vector
        'along the virtual X-Axis"

        PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
        SCM = 500   'Note: SCM is an acronym for "Secondary Scale Multiplier".
                    '      This value was found by experimentation when it was
                    '      observed that the Scale factor by itself was
                    '      too small without a multiplier.

        LBWF.NodeSX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
        'The projection of this vector along the virtual Y-axis
        'is the dot product of this vector with the unit vector
        'along the virtual Y-Axis"

        PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
        LBWF.NodeSY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
    next i
 
    '''''''''''''''''''''''''''''''''''''''''
    'AXES NODES *** AXES NODES *** AXES NODES 
    '''''''''''''''''''''''''''''''''''''''''

    for i = 1 to 4
 
        'Establish the vector components of the Camera-to-Node Vector
        Cam2NodeX = (LBWF.AxesWorldX(i) - LBWF.CamX(1))
        Cam2NodeY = (LBWF.AxesWorldY(i) - LBWF.CamY(1))
        Cam2NodeZ = (LBWF.AxesWorldZ(i) - LBWF.CamZ(1))
 
        numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
        denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
        t = (numerator / denominator)
 
        ipX = LBWF.CamX(1) + Cam2NodeX*t
        ipY = LBWF.CamY(1) + Cam2NodeY*t
        ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
        Ctr2ipX = (ipX - LBWF.VCtrX(1))
        Ctr2ipY = (ipY - LBWF.VCtrY(1))
        Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
        PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
        SCM = 500   
 
        LBWF.AxesScreenX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
        PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
        LBWF.AxesScreenY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
    next i
 
    'If the "visible" property of the axes is set to 1,
    'then draw the axes on the screen...
    
    if (LBWF.AxesVisible(1) = 1) then
 
        'Set the line thickness for the axes...
        print #main.wfscene, "size "; LBWF.AxesLineThickness(1)
 
        'Draw the x-axis (set color for x-axis first)
        print #main.wfscene, "color "; LBWF.XaxisColor$(1)
        x1 = LBWF.AxesScreenX(1) : y1 = LBWF.AxesScreenY(1)
        x2 = LBWF.AxesScreenX(2) : y2 = LBWF.AxesScreenY(2)
        print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
 
        'Draw the y-axis (set color for y-axis first)
        print #main.wfscene, "color "; LBWF.YaxisColor$(1)
        x1 = LBWF.AxesScreenX(1) : y1 = LBWF.AxesScreenY(1)
        x2 = LBWF.AxesScreenX(3) : y2 = LBWF.AxesScreenY(3)
        print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
 
        'Draw the z-axis (set color for z-axis first)
        print #main.wfscene, "color "; LBWF.ZaxisColor$(1)
        x1 = LBWF.AxesScreenX(1) : y1 = LBWF.AxesScreenY(1)
        x2 = LBWF.AxesScreenX(4) : y2 = LBWF.AxesScreenY(4)
        print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
 
        'Reset the line thickness back to 1...
        print #main.wfscene, "size 1"
 
    end if
 
    'Now that the screen coordinates of all of the nodes
    'have been determined, it is time to draw all of the
    'lines.  Draw the lines one object at a time, so
    'that line colors can be changed between objects...

    For obj = 1 to LBWF.ObjectCount(1)
 
    'Draw the object only if its "visible" property is set to 1...
    
    if (LBWF.ObjectVisible(obj) = 1) then
 
        'Set the drawing color for the object...
        DrawingColor$ = LBWF.ObjectColor$(obj)
        print #main.wfscene, "color "; DrawingColor$
 
        'Set the line thickness for the object...
        LineThickness = LBWF.ObjectLineThickness(obj)
        print #main.wfscene, "size "; LineThickness
 
        FirstLine = LBWF.ObjectFirstLine(obj)
        LastLine  = LBWF.ObjectLastLine(obj)
 
        for i = FirstLine to LastLine
            x1 = LBWF.NodeSX(LBWF.LineInode(i))
            y1 = LBWF.NodeSY(LBWF.LineInode(i))
            x2 = LBWF.NodeSX(LBWF.LineJnode(i))
            y2 = LBWF.NodeSY(LBWF.LineJnode(i))
 
            print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
        next i
 
        'If needed, pause during testing of drawn objects...
        'PPP = FF.LBWF.PauseMilliseconds(1000)

    end if
 
 
    next obj
 
    'Reset the default line thickness back to 1...
    print #main.wfscene, "size 1" 
 
    'Set the default drawing color back to black...
    print #main.wfscene, "color black"
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestLibraryResources$()
 
    FF.LBWF.RequestLibraryResources$ = str$(LBWF.NodeResources(1)) + "  " + _
                                       str$(LBWF.LineResources(1)) + "  " + _
                                       str$(LBWF.ObjectResources(1))
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestRemainingResources$()
 
    RemainingNodes   = LBWF.NodeResources(1) - LBWF.NodeCount(1)
    RemainingLines   = LBWF.LineResources(1) - LBWF.LineCount(1)
    RemainingObjects = LBWF.ObjectResources(1) - LBWF.ObjectCount(1)
 
    FF.LBWF.RequestRemainingResources$ = str$(RemainingNodes) + "  " + _
                                         str$(RemainingLines) + "  " + _
                                         str$(RemainingObjects)
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    'Determine the object on which to generate a report
    'by comparing the name argument against a list of object names...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenterX = LBWF.ObjectCenterX(ObjectOfReport)
    ObjectCenterY = LBWF.ObjectCenterY(ObjectOfReport)
    ObjectCenterZ = LBWF.ObjectCenterZ(ObjectOfReport)
 
    FF.LBWF.RequestObjectGeometricCenter$ = str$(ObjectCenterX) + "  " + _
                                            str$(ObjectCenterY) + "  " + _
                                            str$(ObjectCenterZ)
 
end Function
'''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.MoveObjectAbsolute(ObjectName$, pX, pY, pZ)
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    currentCenterX = val(word$(ObjectCenter$, 1))
    currentCenterY = val(word$(ObjectCenter$, 2))
    currentCenterZ = val(word$(ObjectCenter$, 3))
 
    transX = pX - currentCenterX
    transY = pY - currentCenterY
    transZ = pZ - currentCenterZ
 
    'Now, call the function which translates an object.
    'This will translate the object to the absolute
    'point identified by (pX,pY,pZ).
    
    AAA = FF.LBWF.TranslateObject(ObjectName$, transX, transY, transZ)
 
end Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectColor$(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectColor$ = LBWF.ObjectColor$(ObjectOfReport)
 
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectLineThickness(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectLineThickness = LBWF.ObjectLineThickness(ObjectOfReport)
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.HideAllObjects()
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        LBWF.ObjectVisible(i) = 0
    next i
 
 
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowAllObjects()
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        LBWF.ObjectVisible(i) = 1
    next i
 
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.RequestObjectType$(ObjectName$)
 
    ObjectToIdentifyType = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToIdentifyType = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectType$ = LBWF.ObjectType$(ObjectToIdentifyType)
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.RotateObjectAboutY(ObjectName$, YRotationInDegrees)
 
    'Multiply the rotation angle by (-1)
    YRotationInDegrees = (-1) * YRotationInDegrees
 
    pi = 3.14159
    YRotRads = (YRotationInDegrees/360)*(2*pi)
 
    ObjectToRotate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToRotate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    CenterX = val(word$(ObjectCenter$,1))
    CenterY = val(word$(ObjectCenter$,2))
    CenterZ = val(word$(ObjectCenter$,3))
 
 
    ObjectsFirstNode = LBWF.ObjectFirstNode(ObjectToRotate)
    ObjectsLastNode  = LBWF.ObjectLastNode(ObjectToRotate)
 
    for i = ObjectsFirstNode to ObjectsLastNode
 
        deltaX = (LBWF.NodeWX(i) - CenterX)
        deltaZ = (LBWF.NodeWZ(i) - CenterZ)
        R      = sqr(deltaX^2 + deltaZ^2)
        OldAngleRads = FF.LBWF.ATAN2(deltaX, deltaZ)
 
        NewAngleRads = OldAngleRads + YRotRads
 
        LBWF.NodeWX(i) = CenterX + R*cos(NewAngleRads)
        LBWF.NodeWZ(i) = CenterZ + R*sin(NewAngleRads)
 
    next i
 
 
 
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.RotateObjectAboutX(ObjectName$, XRotationInDegrees)
 
    'Multiply the rotation angle by (-1)...
    XRotationInDegrees = (-1)*XRotationInDegrees
 
    pi = 3.14159
    XRotRads = (XRotationInDegrees/360)*(2*pi)
 
    ObjectToRotate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToRotate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    CenterX = val(word$(ObjectCenter$,1))
    CenterY = val(word$(ObjectCenter$,2))
    CenterZ = val(word$(ObjectCenter$,3))
 
    ObjectsFirstNode = LBWF.ObjectFirstNode(ObjectToRotate)
    ObjectsLastNode  = LBWF.ObjectLastNode(ObjectToRotate)
 
    for i = ObjectsFirstNode to ObjectsLastNode
 
        deltaY = (LBWF.NodeWY(i) - CenterY)
        deltaZ = (LBWF.NodeWZ(i) - CenterZ)
        R      = sqr(deltaY^2 + deltaZ^2)
        OldAngleRads = FF.LBWF.ATAN2(deltaZ, deltaY)
 
        NewAngleRads = OldAngleRads + XRotRads
 
        LBWF.NodeWZ(i) = CenterZ + R*cos(NewAngleRads)
        LBWF.NodeWY(i) = CenterY + R*sin(NewAngleRads)
 
    next i
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RotateObjectAboutZ(ObjectName$, ZRotationInDegrees)
 
    pi = 3.14159
    ZRotRads = (ZRotationInDegrees/360)*(2*pi)
 
    ObjectToRotate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToRotate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    CenterX = val(word$(ObjectCenter$,1))
    CenterY = val(word$(ObjectCenter$,2))
    CenterZ = val(word$(ObjectCenter$,3))
 
    ObjectsFirstNode = LBWF.ObjectFirstNode(ObjectToRotate)
    ObjectsLastNode  = LBWF.ObjectLastNode(ObjectToRotate)
 
    for i = ObjectsFirstNode to ObjectsLastNode
 
        deltaY = (LBWF.NodeWY(i) - CenterY)
        deltaX = (LBWF.NodeWX(i) - CenterX)
        R      = sqr(deltaY^2 + deltaX^2)
        OldAngleRads = FF.LBWF.ATAN2(deltaX, deltaY)
 
        NewAngleRads = OldAngleRads + ZRotRads
 
        LBWF.NodeWX(i) = CenterX + R*cos(NewAngleRads)
        LBWF.NodeWY(i) = CenterY + R*sin(NewAngleRads)
 
    next i
 
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectVisibleState(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectVisibleState = LBWF.ObjectVisible(ObjectOfReport)
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectExtents$(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FirstNode = LBWF.ObjectFirstNode(ObjectOfReport)
    LastNode  = LBWF.ObjectLastNode(ObjectOfReport)
 
    Xmin = LBWF.NodeWX(FirstNode)
    Xmax = LBWF.NodeWX(FirstNode)
    Ymin = LBWF.NodeWY(FirstNode)
    Ymax = LBWF.NodeWY(FirstNode)
    Zmin = LBWF.NodeWZ(FirstNode)
    Zmax = LBWF.NodeWZ(FirstNode)
 
    for i = (FirstNode + 1) to LastNode
 
        if (LBWF.NodeWX(i) < Xmin) then
            Xmin = LBWF.NodeWX(i)
        end if
        if (LBWF.NodeWX(i) > Xmax) then
            Xmax = LBWF.NodeWX(i)
        end if
 
        if (LBWF.NodeWY(i) < Ymin) then
            Ymin = LBWF.NodeWY(i)
        end if
        if (LBWF.NodeWY(i) > Ymax) then
            Ymax = LBWF.NodeWY(i)
        end if
 
        if (LBWF.NodeWZ(i) < Zmin) then
            Zmin = LBWF.NodeWZ(i)
        end if
        if (LBWF.NodeWZ(i) > Zmax) then
            Zmax = LBWF.NodeWZ(i)
        end if
 
    next i
 
    FF.LBWF.RequestObjectExtents$ = str$(Xmin) + " " + str$(Xmax) + " " + str$(Ymin) + _
       " " + str$(Ymax) + " " + str$(Zmin) + " " + str$(Zmax)
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ATAN2(x, y)
 
    pi = 3.14159265
    Result$ = "Undetermined"
    If (x = 0) and (y > 0) then
        FF.LBWF.ATAN2 = pi / 2
        Result$ = "Determined"
    end if
    if (x = 0) and (y < 0) then
        FF.LBWF.ATAN2 = 3 * pi / 2
        Result$ = "Determined"
    end if
    if (x > 0) and (y = 0) then
        FF.LBWF.ATAN2 = 0
        Result$ = "Determined"
    end if
    if (x < 0) and (y = 0) then
        FF.LBWF.ATAN2 = pi
        Result$ = "Determined"
    end if
    if (x = 0) and (y = 0) then
        FF.LBWF.ATAN2 = 0
        Result$ = "Determined"
    end if
 
    If Result$ = "Determined" then [End.of.function]
 
 
    BaseAngle = ATN(abs(y)/abs(x))
    If (x > 0) and (y > 0) then FF.LBWF.ATAN2 = BaseAngle
    If (x < 0) and (y > 0) then FF.LBWF.ATAN2 = pi - BaseAngle
    If (x < 0) and (y < 0) then FF.LBWF.ATAN2 = pi + BaseAngle
    If (x > 0) and (y < 0) then FF.LBWF.ATAN2 = 2*pi - BaseAngle
 
    [End.of.function]
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.FindPerpendicularDistance$(xa, ya, xb, yb, xc, yc)
 
    Distance.Is.Found = 0
 
    'Handle the case where the line between (xa,ya) and (xb,yb)
    'is a horizontal line...
    
    if (ya = yb) then
 
        primaryLineType$ = "horizontal"
        distance = abs(yc - ya)
        xd = xc
        yd = ya
        Distance.Is.Found = 1
 
    end if
 
    if (Distance.Is.Found = 1) then [Distance.Calc.Is.Complete] 
 
    'Handle the case where the line between (xa,ya) and (xb,yb)
    'is a vertical line...
    
    if (xa = xb) then
 
        primaryLineType$ = "vertical"
        distance = abs(xc - xa)
        xd = xa
        yd = yc
        Distance.Is.Found = 1
 
    end if
 
    if (Distance.Is.Found = 1) then [Distance.Calc.Is.Complete]
 
    'If program control has arrived at this location, then
    'the line between (xa, ya) and (xb, yb) is a diagonal
    'line.  Find the distance for this case...
    
    primaryLineType$ = "diagonal"
 
    'slope of the primary line...
    m1 = (ya - yb)/(xa - xb)
 
    'y-intercept of the primary line...
    b1 = ya - (m1 * xa)
 
    'slope of the perpendicular line...
    m2 = (-1)/m1
 
    'y-intercept of the perpendicular line...
    b2 = yc - (m2 * xc)
 
    'Calculate xd and yd, which are the coordinates
    'of the point where the perpendicular line intersects
    'the primary line...

    xd = (b2 - b1)/(m1 - m2)
    yd = (m2 * xd) + b2
 
    'Find the distance between (xc, yc) and (xd, yd)...
    distance = sqr((xc-xd)^2 + (yc-yd)^2)
 
    [Distance.Calc.Is.Complete]
 
    'Find out if the intersecting point in question
    'actually resides between (xa, ya) and (xb, yb)...
    
    xdydBetweenEndpoints$ = "no"
 
    if (primaryLineType$ = "vertical") then
 
        if ((yd >= min(ya,yb)) and (yd <= max(ya,yb))) then
            xdydBetweenEndpoints$ = "yes"
        end if
 
    end if 
 
    if (primaryLineType$ = "horizontal") then
 
        if ((xd >= min(xa,xb)) and (xd <= max(xa,xb))) then
            xdydBetweenEndpoints$ = "yes"
        end if 
 
    end if
 
    if (primaryLineType$ = "diagonal") then
 
        if ((xd >= min(xa,xb)) and (xd <= max(xa,xb))) then
            xdydBetweenEndpoints$ = "yes"
        end if
 
    end if
 
 
    FF.LBWF.FindPerpendicularDistance$ = str$(distance) + "  " + xdydBetweenEndpoints$
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' LBWF.ObjectFirstNode(LBWF.ObjectResources(1))
' LBWF.ObjectLastNode(LBWF.ObjectResources(1))

 
'LBWF.ObjectCount(1)

' LBWF.ObjectVisible(LBWF.ObjectResources(1))

 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
'LBWF.ObjectName$(LBWF.ObjectResources(1))

 
'''''''''''''''''''''''''''''''''''''''''''''



Top of Page




Source Demo2.bas

'''''''''''''''''''''''''''''''''''''''''''
'  demo2.bas                              '
'                                         '
'  LBWF Library ("Wire") Version 1.0      '
'                                         '
'''''''''''''''''''''''''''''''''''''''''''
'                                         '
'  Tomas J. Nally                         '
'  steelweaver52@aol.com                  '
'                                         '
'''''''''''''''''''''''''''''''''''''''''''

 
    True = 1 : False = 0
    pi = 3.14159
 
'Set initial camera angle
CamAngleInitialDegrees = 290
CamAngleInitialRadians = (CamAngleInitialDegrees/360)*(2*pi)
 
'Set camera distance from origin...
CamDistance = 1200
 
CamX = CamDistance * cos(CamAngleInitialRadians)
CamX$ = using("####.#", CamX)
CamZ = CamDistance * sin((-1)*CamAngleInitialRadians)
CamZ$ = using("####.#", CamZ)
CamY = 950
 
CamPosKnobCaptured = 0
 
ZoomControlKnobCaptured = 0
 
 
 
gosub [Initialize.Liberty.BASIC.WireFrame.Library]
 
 
[InitColors]
    'Please use default colors when possible.
    'ForegroundColor$ = "Black"
    'BackgroundColor$ = "Buttonface"
    'TexteditorColor$ = "White"
    'TextboxColor$    = "White"
    'ComboboxColor$   = "White"
    'ListboxColor$    = "White"

[WindowSetup]
    NOMAINWIN
    WindowWidth = 920 : WindowHeight = 640
    UpperLeftX = INT((DisplayWidth-WindowWidth)/2)
    UpperLeftY = INT((DisplayHeight-WindowHeight)/2)
 
[ControlSetup]
Menu        #main, "&File" , "E&xit", [btnQuit.click]
 
'The Main Graphic Box...
graphicbox  #main.wfscene, 170, 20, 720, 540
 
'The camera position controls...
statictext  #main.statCamPos, "Camera Position", 30, 70, 110, 20
graphicbox  #main.gboxCamPos, 15, 95, 140, 140
 
statictext  #main.statXLabel, "x : ", 20, 245, 30, 20
statictext  #main.statXPosit, CamX$,50, 245, 90, 20
 
statictext  #main.statZLabel, "z : ", 20, 265, 30, 20
statictext  #main.statZPosit, CamZ$,50, 265, 90, 20
 
'The zoom controls...
statictext  #main.statZoomIn,  "Zoom In", 80, 315, 70, 20
statictext  #main.statZoomFac, "ZoomFac", 80, 400, 70, 20
statictext  #main.statZoomOut, "Zoom Out", 80, 480, 70, 20
graphicbox  #main.gboxZoom, 25, 310, 50, 190
 
 
'The quit button...
button      #main.btnQuit, "Quit", [btnQuit.click], UL, 15, 525, 130, 35
 
 
 
Open "Wire 1.0 - demo2.bas" for Window as #main
    #main "trapclose [btnQuit.click]"
    #main.wfscene "down; fill White; flush"
    #main.wfscene "setfocus"
 
    #main.gboxCamPos "down; fill White; flush"
    #main.gboxCamPos "setfocus; when leftButtonMove [CamPosLeftButtonMove]"
    #main.gboxCamPos "when leftButtonDown [CamPosLeftButtonDown]"
    #main.gboxCamPos "when leftButtonUp   [CamPosLeftButtonUp]"
 
    #main.gboxZoom "down; fill White; flush"
    #main.gboxZoom "setfocus; when leftButtonMove [ZoomControlLeftButtonMove]"   '[MouseChange3]"
    #main.gboxZoom "when leftButtonDown [ZoomControlLeftButtonDown]"
    #main.gboxZoom "when leftButtonUp   [ZoomControlLeftButtonUp]"
    #main "font arial 10"
 
    'Set up the camera position graphicbox...
    CamPosGBCenterX = 70
    CamPosGBCenterY = 70
    CamPosAxisLineThickness = 3
    CamPosXAxisColor$ = "blue"
    CamPosZAxisColor$ = "darkgreen"
    CamPosAxisLength = 60
 
 
    AAA = Setup.Camera.Position.GraphicBox(CamPosGBCenterX,CamPosGBCenterY,CamPosAxisLineThickness, _
       CamPosXAxisColor$,CamPosZAxisColor$,CamPosAxisLength)
 
    'Draw the camera position handle and knob...
    HandleKnobRadius = 6
    HandleLength = CamPosAxisLength
    HandleThickness = 4
    HandleColor$ = "darkpink"
    HandleAngleDegrees = CamAngleInitialDegrees
    OldHandleAngleDegrees = HandleAngleDegrees
    HandleDrawingRule$ = "xor"
    AAA$ = Draw.Camera.Position.Handle$(HandleKnobRadius,HandleLength,HandleThickness,HandleColor$,_
        HandleAngleDegrees,HandleDrawingRule$,CamPosGBCenterX,CamPosGBCenterY)
 
    KnobCenterX = val(word$(AAA$, 1)): KnobCenterY = val(word$(AAA$, 2))
 
    'Draw the Zoom Control Knob
    ZCKnobWidth     = 40
    ZCKnobHgt       = 10
    ZCKnobThick     = 3
    ZCKnobColor$    = "darkpink"
    ZoomFacMinValue = 0.5
    ZoomFacMaxValue = 10.0   'test at 10
    ZoomFac         = 2.00 : print #main.statZoomFac, using("##.##", ZoomFac)
    OldZoomFac      = ZoomFac
    ZCKnobDrawRule$ = "xor"
 
    AAA$ = Draw.Zoom.Control.Knob$(ZCKnobWidth,ZCKnobHgt,ZCKnobThick,ZCKnobColor$, _
                                   ZoomFacMinValue, ZoomFacMaxValue, ZoomFac, _
                                   ZCKnobDrawRule$)
 
    ZCKnobMiddleX    = val(word$(AAA$, 1))
    ZCKnobMiddleY    = val(word$(AAA$, 2))
    ZCKnobproportion = val(word$(AAA$, 3))
    MinCenterY       = val(word$(AAA$, 4))
    MaxCenterY       = val(word$(AAA$, 5))
 
    'Set the camera location...
    AAA = FF.LBWF.CameraLocation(CamX, CamY, CamZ)
 
    'Set the viewing center...
    VCtrX = 0
    VCtrY = 0
    VCtrZ = 0
    AAA = FF.LBWF.ViewingCenter(VCtrX, VCtrY, VCtrZ)
 
    'Set the zoom factor...
    AAA = FF.LBWF.ZoomFactor(ZoomFac)
 
    'Set the screen center to the center point of the graphicbox...
    ScreenCenterX = 360 : ScreenCenterY = 270
    AAA = FF.LBWF.ScreenCenter(ScreenCenterX, ScreenCenterY)
 
    'Set a background color for the graphicbox...
    AAA = FF.LBWF.BackGroundColor("white")
 
    'Show the axes...
    AAA = FF.LBWF.ShowAxes()
 
    'Create a grid object...
    GridName$ = "grid1"
    NumUnitsXdirection = 10
    NumUnitsZdirection = 10
    UnitSize = 80
    GridColor$ = "lightgray"
    AAA = FF.LBWF.CreateGridObject(GridName$, NumUnitsXdirection, NumUnitsZdirection, UnitSize, GridColor$)
 
    'Create "buildings" on the -z side of the axes...
    
    bldgColor$ = "darkred"
    for i = 1 to 6
        ObjectName$ = "bldgA" + str$(i)
        xdim = 30 + 30*rnd(1)
        zdim = 30 + 30*rnd(1)
        boxheight = 90 + 90*rnd(1)
        AAA = FF.LBWF.CreateBox(ObjectName$, xdim, zdim, boxheight, bldgColor$)
        AAA = FF.LBWF.TranslateObject(ObjectName$, 200 - (i-1)*80, 0, -70 - 20*rnd(1))
        'AAA = FF.LBWF.ObjectSetLineThickness(ObjectName$, 2)
    next i
 
    for i = 1 to 6
        ObjectName$ = "bldgB" + str$(i)
        xdim = 30 + 30*rnd(1)
        zdim = 30 + 30*rnd(1)
        boxheight = 90 + 90*rnd(1)
        AAA = FF.LBWF.CreateBox(ObjectName$, xdim, zdim, boxheight, bldgColor$)
        AAA = FF.LBWF.TranslateObject(ObjectName$, 200 - (i-1)*80, 0, 70 + 20*rnd(1))
        'AAA = FF.LBWF.ObjectSetLineThickness(ObjectName$, 2)
    next i
 
    'Import the spacecraft...
    AAA = FF.LBWF.CreateComplexObject("Spacecraft1", "Spacecraft01.cplx", "black")
    AAA = FF.LBWF.TranslateObject("Spacecraft1", 150, 0, 0)
    AAA = FF.LBWF.RotateObjectAboutY("Spacecraft1", 180)
 
    'Point the camera at the spacecraft...
    AAA = FF.LBWF.PointCameraAtObject("Spacecraft1")
 
    'Clear the graphic screen and draw all objects...
    AAA = FF.LBWF.ClearGraphicScreen()
    AAA = FF.LBWF.DrawAllObjects()
 
 
 
[loop]
    Wait
 
[quit]
    close #main : END
 
[CamPosLeftButtonDown]
 
    DeltaX = (MouseX - KnobCenterX)
    DeltaY = (MouseY - KnobCenterY)
    PointerToKnobDistance = sqr(DeltaX^2 + DeltaY^2)
 
    if (PointerToKnobDistance < HandleKnobRadius) then
        CamPosKnobCaptured = 1
    end if
 
 
    Wait
 
[CamPosLeftButtonMove]
    'MouseX and MouseY contain mouse coordinates
    
    if (CamPosKnobCaptured = 1) then 
 
        OldHandleAngleDegrees = HandleAngleDegrees
 
        'Undraw the handle and knob at the old location...
        AAA$ = Draw.Camera.Position.Handle$(HandleKnobRadius,HandleLength,HandleThickness,HandleColor$,_
             OldHandleAngleDegrees,HandleDrawingRule$,CamPosGBCenterX,CamPosGBCenterY)
 
        'Find the new handle angle...
        CamPosDeltaX = (MouseX - CamPosGBCenterX)
        CamPosDeltaY = (CamPosGBCenterY - MouseY)
 
        HandleAngleRadians = FF.LBWF.ATAN2(CamPosDeltaX, CamPosDeltaY)
        HandleAngleDegrees = (HandleAngleRadians/(2*pi))*360
 
        'Redraw the handle and the knob at the new location...
        AAA$ = Draw.Camera.Position.Handle$(HandleKnobRadius,HandleLength,HandleThickness,HandleColor$,_
             HandleAngleDegrees,HandleDrawingRule$,CamPosGBCenterX,CamPosGBCenterY)
        KnobCenterX = val(word$(AAA$, 1)): KnobCenterY = val(word$(AAA$, 2))
 
        CamAngleRadians = HandleAngleRadians
        CamX = CamDistance * cos(CamAngleRadians)
        CamX$ = using("####.#", CamX)
        CamZ = CamDistance * sin((-1)*CamAngleRadians)
        CamZ$ = using("####.#", CamZ)
        print #main.statXPosit, CamX$
        print #main.statZPosit, CamZ$
        AAA = FF.LBWF.CameraLocation(CamX, CamY, CamZ)
        AAA = FF.LBWF.ClearGraphicScreen()
        AAA = FF.LBWF.DrawAllObjects()
 
    end if
 
 
    wait
 
 
 
 
 
[CamPosLeftButtonUp]
 
    CamPosKnobCaptured = 0
 
    Wait
 
[ZoomControlLeftButtonDown]
 
    ZoomControlDeltaX = abs(MouseX - ZCKnobMiddleX)
    ZoomControlDeltaY = abs(MouseY - ZCKnobMiddleY)
 
    if ((ZoomControlDeltaX < ZCKnobWidth/2) and (ZoomControlDeltaY < ZCKnobHgt/2)) then
        ZoomControlKnobCaptured = 1
    end if
 
    Wait
 
 
[ZoomControlLeftButtonMove]
    'MouseX and MouseY contain mouse coordinates
    
    if (ZoomControlKnobCaptured = 1) then
 
        'Undraw the zoom control knob at the old location...
        AAA$ = Draw.Zoom.Control.Knob$(ZCKnobWidth,ZCKnobHgt,ZCKnobThick,ZCKnobColor$, _
                                       ZoomFacMinValue, ZoomFacMaxValue, OldZoomFac, _
                                       ZCKnobDrawRule$)
 
        'Find the new ZoomFac which should be based on MouseY...
        ZoomFac = ZoomFacMinValue + ((MinCenterY - MouseY)/(MinCenterY - MaxCenterY))*(ZoomFacMaxValue - ZoomFacMinValue)
 
        if (ZoomFac < ZoomFacMinValue) then
            ZoomFac = ZoomFacMinValue
        end if
 
        if (ZoomFac > ZoomFacMaxValue) then
            ZoomFac = ZoomFacMaxValue
        end if
 
        'Draw the zoom control knob in accordance with the new zoom factor...
        AAA$ = Draw.Zoom.Control.Knob$(ZCKnobWidth,ZCKnobHgt,ZCKnobThick,ZCKnobColor$, _
                                       ZoomFacMinValue, ZoomFacMaxValue, ZoomFac, _
                                       ZCKnobDrawRule$)
 
        print #main.statZoomFac, using("##.##", ZoomFac)
 
        ZCKnobMiddleX    = val(word$(AAA$, 1))
        ZCKnobMiddleY    = val(word$(AAA$, 2))
        ZCKnobproportion = val(word$(AAA$, 3))
        MinCenterY       = val(word$(AAA$, 4))
        MaxCenterY       = val(word$(AAA$, 5))
 
        OldZoomFac = ZoomFac
 
        AAA = FF.LBWF.ZoomFactor(ZoomFac)
        AAA = FF.LBWF.ClearGraphicScreen()
        AAA = FF.LBWF.DrawAllObjects()
 
    end if
 
 
 
    wait
 
[ZoomControlLeftButtonUp]
 
    ZoomControlKnobCaptured = 0
 
    Wait
 
 
[btnQuit.click]
    close #main : END
    wait
 
'''''''''''''''''''''''''''''''''''''''''

Function Draw.Zoom.Control.Knob$(ZCKnobWidth,ZCKnobHgt,ZCKnobThick,ZCKnobColor$,_
        ZoomFacMinValue,ZoomFacMaxValue,ZoomFac,ZCKnobDrawRule$)
 
    'The dimensions of the graphicbox for the
    'zoom control are 50 wide by 190 tall.
    'The center of the knob should go no higher
    'than...
    
    MaxCenterY = 0 + 5 + ZCKnobHgt/2
 
    'The center of the knob should go no lower
    'than...
    
    MinCenterY = 190 - 5 - ZCKnobHgt/2
 
    'The total vertical range of motion is...
    
    Yrange = (MinCenterY - MaxCenterY)
 
    'Y coordinate of the middle of the ZoomControl Knob...
    KnobMiddleY = MinCenterY - ((ZoomFac - ZoomFacMinValue)/(ZoomFacMaxValue - ZoomFacMinValue))*(Yrange)
 
    'Y coordinate of the Upper left corner of the zoom control knob...
    KnobUpperLeftY = KnobMiddleY - ZCKnobHgt/2
 
    'X coordinate of the Upper left corner of the zoom control knob...
    KnobUpperLeftX = 50/2 - ZCKnobWidth/2
 
    'Send the drawing rule command to the graphicbox for the zoom control...
    'Send the color...
    'Send the line thickness...
    
    print #main.gboxZoom, "rule  "; ZCKnobDrawRule$
    print #main.gboxZoom, "color "; ZCKnobColor$
    print #main.gboxZoom, "size  "; ZCKnobThick
 
    'Draw the knob...
    print #main.gboxZoom, "place "; KnobUpperLeftX; " "; KnobUpperLeftY
    print #main.gboxZoom, "box "; (KnobUpperLeftX+ZCKnobWidth); " ";(KnobUpperLeftY+ZCKnobHgt)
 
    Yproportion = (MinCenterY - KnobMiddleY)/Yrange
 
    Draw.Zoom.Control.Knob$ = str$(50/2) + "  " + str$(KnobMiddleY) + "  " + str$(Yproportion) + "  "
    Draw.Zoom.Control.Knob$ = Draw.Zoom.Control.Knob$ + str$(MinCenterY) + "  " + str$(MaxCenterY)
 
End Function
 
 
 
'''''''''''''''''''''''''''''''''''''''''

Function Setup.Camera.Position.GraphicBox(CamPosGBCenterX,CamPosGBCenterY,CamPosAxisLineThickness,_
      CamPosXAxisColor$,CamPosZAxisColor$,CamPosAxisLength)
 
    'Clear the camera position graphicbox...
    print #main.gboxCamPos, "rule over"
    print #main.gboxCamPos, "cls"
 
    'Set the pen size to the axis line thickness...
    print #main.gboxCamPos, "size "; CamPosAxisLineThickness
 
    'Draw the X-axis and the X character...
    print #main.gboxCamPos, "color "; CamPosXAxisColor$
    print #main.gboxCamPos, "line "; CamPosGBCenterX; " "; CamPosGBCenterY; " "; _
           (CamPosGBCenterX + CamPosAxisLength); " "; CamPosGBCenterY
    placeX = CamPosGBCenterX + CamPosAxisLength - 10
    placeY = CamPosGBCenterY - 5
    print #main.gboxCamPos, "place "; placeX; " "; placeY
    print #main.gboxCamPos, "\X"
 
    'Draw the Z-axis and the Z character ...
    print #main.gboxCamPos, "color "; CamPosZAxisColor$
    print #main.gboxCamPos, "line "; CamPosGBCenterX; " "; CamPosGBCenterY; " "; _
          CamPosGBCenterX; " "; (CamPosGBCenterY + CamPosAxisLength)
 
    placeX = CamPosGBCenterX + 5
    placeY = CamPosGBCenterY + CamPosAxisLength
    print #main.gboxCamPos, "place "; placeX; " "; placeY
    print #main.gboxCamPos, "\Z"
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''

Function Draw.Camera.Position.Handle$(HandleKnobRadius,HandleLength,HandleThickness,HandleColor$,_
        HandleAngleDegrees,HandleDrawingRule$,CamPosGBCenterX,CamPosGBCenterY)
 
    'Set the drawing rule, the pen size, and the drawing color...
    print #main.gboxCamPos, "rule "; HandleDrawingRule$
    print #main.gboxCamPos, "color "; HandleColor$
    print #main.gboxCamPos, "size "; HandleThickness
 
 
    'Find the coordinates of the handle knob based on the
    'handle angle and the handle length...
    pi = 3.14159
    HandleAngleRadians  = (HandleAngleDegrees/360)*(2*pi)
    KnobCenterX = CamPosGBCenterX + HandleLength*cos(HandleAngleRadians)
    KnobCenterY = CamPosGBCenterY - HandleLength*sin(HandleAngleRadians)
 
    'Draw the knob first...
    print #main.gboxCamPos, "place "; KnobCenterX ; " "; KnobCenterY
    print #main.gboxCamPos, "circle "; HandleKnobRadius
 
    'Then draw the line representing the handle...
    print #main.gboxCamPos, "line "; CamPosGBCenterX; " "; CamPosGBCenterY ; " "; KnobCenterX; " "; KnobCenterY
 
    Draw.Camera.Position.Handle$ = str$(KnobCenterX) + "  " + str$(KnobCenterY)
 
End Function
 
 
 
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''

'---Insert library below this line----

 
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'        Begin Liberty BASIC WireFrame Library             '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
'''''''''''''''''''''''''''''''''''''''''''''''''''
'List of Liberty BASIC Wire Frame Library Functions
'''''''''''''''''''''''''''''''''''''''''''''''''''
'
'function count = 53
'
'Function FF.LBWF.Camera()
'Function FF.LBWF.CameraLocation()
'Function FF.LBWF.ViewingCenter()
'Function FF.LBWF.ZoomFactor()
'Function FF.LBWF.ScreenCenter()
'Function FF.LBWF.PointCameraAtObject()
'Function FF.LBWF.BackGroundColor()
'Function FF.LBWF.ShowAxes()
'Function FF.LBWF.HideAxes()
'Function FF.LBWF.SetAxesProperties()
'
'Function FF.LBWF.CreateBox()
'Function FF.LBWF.CreateCylinder()
'Function FF.LBWF.CreatePyramid()
'Function FF.LBWF.CreateCone()
'Function FF.LBWF.CreatePolygon()
'Function FF.LBWF.CreateGridObject()
'Function FF.LBWF.CreateDome()
'Function FF.LBWF.CreateLine()
'Function FF.LBWF.CreateCyl2()
'Function FF.LBWF.CreateComplexObject()
'
'Function FF.LBWF.TranslateObject()
'Function FF.LBWF.HideObject()
'Function FF.LBWF.ShowObject()
'Function FF.LBWF.ObjectSetColor()
'Function FF.LBWF.ObjectSetLineThickness()
'Function FF.LBWF.MoveObjectAbsolute()
'Function FF.LBWF.RotateObjectAboutY()
'Function FF.LBWF.RotateObjectAboutX()
'Function FF.LBWF.RotateObjectAboutZ()
'
'Function FF.LBWF.HideObjectsOfType()
'Function FF.LBWF.ShowObjectsOfType()
'Function FF.LBWF.TranslateObjectsOfType()
'Function FF.LBWF.DrawObjectsOfType()
'Function FF.LBWF.ObjectAssignCustomType()
'
'
'Function FF.LBWF.HideAllObjects()
'Function FF.LBWF.ShowAllObjects()
'
'Function FF.LBWF.ClearGraphicScreen()
'Function FF.LBWF.DrawObject()
'Function FF.LBWF.DrawAllObjects()
'
'Function FF.LBWF.LBWFVersion$()
'Function FF.LBWF.About()
'Function FF.LBWF.PauseMilliseconds()
'Function FF.LBWF.PauseUsingTimer()
'Function FF.LBWF.ZeroAllData()
'
'Function FF.LBWF.RequestLibraryResources$()
'Function FF.LBWF.RequestRemainingResources$()
'Function FF.LBWF.RequestObjectGeometricCenter$()
'Function FF.LBWF.RequestObjectColor$()
'Function FF.LBWF.RequestObjectLineThickness()
'Function FF.LBWF.RequestObjectType$()
'Function FF.LBWF.RequestObjectExtents$()
'Function FF.LBWF.RequestObjectVisibleState()
'Function FF.LBWF.RequestObjectNameFromXY$()
'
'
'Function FF.LBWF.ATAN2()
'Function FF.LBWF.FindPerpendicularDistance$()
'

 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
[Initialize.Liberty.BASIC.WireFrame.Library]
 
dim LBWF.CamX(1)
dim LBWF.CamY(1)
dim LBWF.CamZ(1)
dim LBWF.VCtrX(1)
dim LBWF.VCtrY(1)
dim LBWF.VCtrZ(1)
dim LBWF.ZoomFac(1)
dim LBWF.BackGroundColor$(1)
dim LBWF.VersionNumber$(1)
dim LBWF.NodeResources(1)
dim LBWF.LineResources(1)
dim LBWF.ObjectResources(1)
 
LBWF.CamX(1) = 200
LBWF.CamY(1) = 200
LBWF.CamZ(1) = 200
LBWF.VCtrX(1) = 0
LBWF.VCtrY(1) = 0
LBWF.VCtrZ(1) = 0
LBWF.ZoomFac(1) = 1
LBWF.BackGroundColor$(1) = "white"
LBWF.VersionNumber$(1) = "0.6a"
 
LBWF.NodeResources(1) = 4000
LBWF.LineResources(1) = 4000
LBWF.ObjectResources(1) = 500
 
 
dim LBWF.ScrCenterX(1)
dim LBWF.ScrCenterY(1)
 
LBWF.ScrCenterX(1) = 180
LBWF.ScrCenterY(1) = 180
 
dim LBWF.NodeCount(1)
dim LBWF.LineCount(1)
dim LBWF.ObjectCount(1)
 
LBWF.NodeCount(1) = 0
LBWF.LineCount(1) = 0
LBWF.ObjectCount(1) = 0
 
 
dim LBWF.NodeWX(LBWF.NodeResources(1))
dim LBWF.NodeWY(LBWF.NodeResources(1))
dim LBWF.NodeWZ(LBWF.NodeResources(1))
 
dim LBWF.NodeSX(LBWF.NodeResources(1))
dim LBWF.NodeSY(LBWF.NodeResources(1))
 
dim LBWF.LineInode(LBWF.LineResources(1))
dim LBWF.LineJnode(LBWF.LineResources(1))
 
dim LBWF.ObjectName$(LBWF.ObjectResources(1))
dim LBWF.ObjectColor$(LBWF.ObjectResources(1))
dim LBWF.ObjectFirstNode(LBWF.ObjectResources(1))
dim LBWF.ObjectLastNode(LBWF.ObjectResources(1))
 
dim LBWF.ObjectFirstLine(LBWF.ObjectResources(1))
dim LBWF.ObjectLastLine(LBWF.ObjectResources(1))
 
dim LBWF.ObjectVisible(LBWF.ObjectResources(1))
dim LBWF.ObjectLineThickness(LBWF.ObjectResources(1))
 
dim LBWF.ObjectType$(LBWF.ObjectResources(1))
 
dim LBWF.ObjectCenterX(LBWF.ObjectResources(1))
dim LBWF.ObjectCenterY(LBWF.ObjectResources(1))
dim LBWF.ObjectCenterZ(LBWF.ObjectResources(1))
 
 
    'Information about the axes...
    Dim LBWF.AxesVisible(1)
    LBWF.AxesVisible(1) = 0   'Default state: axes are NOT visible

    Dim LBWF.AxesLength(1)
    LBWF.AxesLength(1) = 50   'The startup length of the axes are 30 units
    
    Dim LBWF.AxesLineThickness(1)
    LBWF.AxesLineThickness(1) = 2   'The startup thickness of the axes objects is 2 pixels

    Dim LBWF.XaxisColor$(1)
    Dim LBWF.YaxisColor$(1)
    Dim LBWF.ZaxisColor$(1)
 
    LBWF.XaxisColor$(1) = "blue"
    LBWF.YaxisColor$(1) = "red"
    LBWF.ZaxisColor$(1) = "darkgreen"
 
 
    Dim LBWF.AxesWorldX(4)
    Dim LBWF.AxesWorldY(4)
    Dim LBWF.AxesWorldZ(4)
 
    Dim LBWF.AxesScreenX(4)
    Dim LBWF.AxesScreenY(4) 
 
    LBWF.AxesWorldX(1) = 0  'These are the world coordinates of
    LBWF.AxesWorldY(1) = 0  'the origin point.
    LBWF.AxesWorldZ(1) = 0  '

    LBWF.AxesWorldX(2) = LBWF.AxesLength(1)  'These are the coordinates of the end
    LBWF.AxesWorldY(2) = 0                   'end point of the X-axis
    LBWF.AxesWorldZ(2) = 0                   '

    LBWF.AxesWorldX(3) = 0                   'These are the coordinates of the
    LBWF.AxesWorldY(3) = LBWF.AxesLength(1)  'endpoint of the Y-axis
    LBWF.AxesWorldZ(3) = 0
 
    LBWF.AxesWorldX(4) = 0                   'These are the coordinates of the
    LBWF.AxesWorldY(4) = 0                   'endpoint of the Z-axis
    LBWF.AxesWorldZ(4) = LBWF.AxesLength(1)  '

'Dimension the arrays for complex objects...

    Dim LBWF.ComplexTextLines$(1000)
 
    dim LBWF.ComplexNodeID(300)
    dim LBWF.ComplexNodeX(300)
    dim LBWF.ComplexNodeY(300)
    dim LBWF.ComplexNodeZ(300)
 
    dim LBWF.ComplexLineID(300)
    dim LBWF.ComplexLineInode(300)
    dim LBWF.ComplexLineJnode(300)
 
 
    Return
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectNameFromXY$(ScreenX, ScreenY, pixelLimit)
 
    'This function identifies the first non-hidden object that
    'contains a line that is located within pixelLimit of the 
    'screen coordinates ScreenX and ScreenY...

 
    FF.LBWF.RequestObjectNameFromXY$ = "null00"
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
 
        'Only evaluate the lines in this object if the visible state
        'of the object has been set to "visible"
        
        If (LBWF.ObjectVisible(i) = 1) then
 
            ObjectToCheck = i
            FirstLineOfObjectToCheck = LBWF.ObjectFirstLine(ObjectToCheck)
            LastLineOfObjectToCheck  = LBWF.ObjectLastLine(ObjectToCheck)
 
            For j = FirstLineOfObjectToCheck to LastLineOfObjectToCheck
 
                TheLine = j
                InodeOfTheLine = LBWF.LineInode(TheLine)
                JnodeOfTheLine = LBWF.LineJnode(TheLine)
                xa = LBWF.NodeSX(InodeOfTheLine)
                ya = LBWF.NodeSY(InodeOfTheLine)
                xb = LBWF.NodeSX(JnodeOfTheLine)
                yb = LBWF.NodeSY(JnodeOfTheLine)
                xc = ScreenX
                yc = ScreenY
 
                Distance$ = FF.LBWF.FindPerpendicularDistance$(xa, ya, xb, yb, xc, yc)
                DistanceComponent    = val(word$(Distance$, 1))
                EvaluationComponent$ = word$(Distance$, 2)
 
                If ((DistanceComponent <= pixelLimit) and (EvaluationComponent$ = "yes")) then 
                    FF.LBWF.RequestObjectNameFromXY$ = LBWF.ObjectName$(i)
                    j = LastLineOfObjectToCheck
                    i = OC
                end if
 
            next j
 
 
        end if
 
    next i
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'LBWF.NodeSX()
'LBWF.NodeSY()

 
'LBWF.LineInode()
'LBWF.LineJnode()

'LBWF.ObjectCount(1) = 0
'LBWF.ObjectVisible(i)
'LBWF.ObjectFirstLine()
'LBWF.ObjectLastLine()

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreateComplexObject(ObjectName$, FileName$, ObjectColor$)
 
    'Read the complex object text file into an array...

    LineCount = 0
 
    open FileName$ for input as #cplx
 
    While (eof(#cplx) <> -1)
        LineCount = LineCount + 1
        Line input #cplx, TheLine$
        LBWF.ComplexTextLines$(LineCount) = TheLine$
    Wend
 
    close #cplx
 
 
    'Parse all of the text data lines into node data and
    'line data of the complex object...

    ComplexNodeCount = 0
    ComplexLineCount = 0
 
    For i = 1 to LineCount
 
    if (lower$(word$(LBWF.ComplexTextLines$(i), 1)) = "node") then
        ComplexNodeCount = ComplexNodeCount + 1
        LBWF.ComplexNodeID(ComplexNodeCount) = val(word$(LBWF.ComplexTextLines$(i), 2))
        LBWF.ComplexNodeX(LBWF.ComplexNodeID(ComplexNodeCount)) = val(word$(LBWF.ComplexTextLines$(i), 3))
        LBWF.ComplexNodeY(LBWF.ComplexNodeID(ComplexNodeCount)) = val(word$(LBWF.ComplexTextLines$(i), 4))
        LBWF.ComplexNodeZ(LBWF.ComplexNodeID(ComplexNodeCount)) = val(word$(LBWF.ComplexTextLines$(i), 5))
    end if
 
    if (lower$(word$(LBWF.ComplexTextLines$(i), 1)) = "line") then
        ComplexLineCount = ComplexLineCount + 1
        LBWF.ComplexLineID(ComplexLineCount) = val(word$(LBWF.ComplexTextLines$(i), 2))
        LBWF.ComplexLineInode(LBWF.ComplexLineID(ComplexLineCount)) = val(word$(LBWF.ComplexTextLines$(i), 3))
        LBWF.ComplexLineJnode(LBWF.ComplexLineID(ComplexLineCount)) = val(word$(LBWF.ComplexTextLines$(i), 4))
    end if
 
    next i
 
    'Integrate the data for the complex object into the database for
    'all of the wireframe objects, starting with the nodes...
    
    NC = LBWF.NodeCount(1)
 
    for i = 1 to ComplexNodeCount
        LBWF.NodeWX(NC + i) = LBWF.ComplexNodeX(i)
        LBWF.NodeWY(NC + i) = LBWF.ComplexNodeY(i)
        LBWF.NodeWZ(NC + i) = LBWF.ComplexNodeZ(i)
    next i
 
    'Define the new lines for this complex object...
    
    LC = LBWF.LineCount(1)
 
    for i = 1 to ComplexLineCount
        LBWF.LineInode(LC + i) = NC + LBWF.ComplexLineInode(i)
        LBWF.LineJnode(LC + i) = NC + LBWF.ComplexLineJnode(i)
    next i
 
    'Define other properties for this complex object...
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = ObjectName$
    LBWF.ObjectColor$(OC + 1)    = ObjectColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + ComplexNodeCount)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + ComplexLineCount)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "complex"
 
    'Determine the geometric center of the complex object.
    'First, for all nodal coordinates, determine the min and
    'max values for the x-, y- and z-directions...
    
    minX = LBWF.ComplexNodeX(1) : maxX = LBWF.ComplexNodeX(1)
    minY = LBWF.ComplexNodeY(1) : maxY = LBWF.ComplexNodeY(1)
    minZ = LBWF.ComplexNodeZ(1) : maxZ = LBWF.ComplexNodeZ(1)
 
    for i = 2 to ComplexNodeCount
 
        if (LBWF.ComplexNodeX(i) < minX) then
            minX = LBWF.ComplexNodeX(i)
        end if
 
        if (LBWF.ComplexNodeX(i) > maxX) then
            maxX = LBWF.ComplexNodeX(i)
        end if
 
        if (LBWF.ComplexNodeY(i) < minY) then
            minY = LBWF.ComplexNodeY(i)
        end if
 
        if (LBWF.ComplexNodeY(i) > maxY) then
            maxY = LBWF.ComplexNodeY(i)
        end if
 
        if (LBWF.ComplexNodeZ(i) < minZ) then
            minZ = LBWF.ComplexNodeZ(i)
        end if
 
        if (LBWF.ComplexNodeZ(i) > maxZ) then
            maxZ = LBWF.ComplexNodeZ(i)
        end if
 
    next i
 
    'The center of the object is equal to the value that 
    'is midway between the min value and the max value...
    LBWF.ObjectCenterX(OC + 1) = (minX + maxX)/2
    LBWF.ObjectCenterY(OC + 1) = (minY + maxY)/2
    LBWF.ObjectCenterZ(OC + 1) = (minZ + maxZ)/2
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + ComplexNodeCount
    LBWF.LineCount(1)   = LBWF.LineCount(1) + ComplexLineCount
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
 
 
 
 
End Function
 
' LBWF.LineInode(LBWF.LineResources(1))
' LBWF.LineJnode(LBWF.LineResources(1))

 
 
' LBWF.NodeWX(i)
' LBWF.NodeWY(i)
' LBWF.NodeWZ(i)

 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.ZeroAllData()
 
LBWF.CamX(1) = 200
LBWF.CamY(1) = 200
LBWF.CamZ(1) = 200
LBWF.VCtrX(1) = 0
LBWF.VCtrY(1) = 0
LBWF.VCtrZ(1) = 0
LBWF.ZoomFac(1) = 1
LBWF.BackGroundColor$(1) = "white"
LBWF.VersionNumber$(1) = "0.6a"
 
LBWF.NodeResources(1) = 4000
LBWF.LineResources(1) = 4000
LBWF.ObjectResources(1) = 500
 
LBWF.ScrCenterX(1) = 180
LBWF.ScrCenterY(1) = 180
 
LBWF.NodeCount(1) = 0
LBWF.LineCount(1) = 0
LBWF.ObjectCount(1) = 0
 
LBWF.AxesVisible(1) = 0   'Default state: axes are NOT visible

LBWF.AxesLength(1) = 50   'The startup length of the axes are 30 units
    
LBWF.AxesLineThickness(1) = 2   'The startup thickness of the axes objects is 2 pixels

LBWF.XaxisColor$(1) = "blue"
LBWF.YaxisColor$(1) = "red"
LBWF.ZaxisColor$(1) = "darkgreen"
 
LBWF.AxesWorldX(1) = 0  'These are the world coordinates of
LBWF.AxesWorldY(1) = 0  'the origin point.
LBWF.AxesWorldZ(1) = 0  '

LBWF.AxesWorldX(2) = LBWF.AxesLength(1)  'These are the coordinates of the end
LBWF.AxesWorldY(2) = 0                   'end point of the X-axis
LBWF.AxesWorldZ(2) = 0                   '

LBWF.AxesWorldX(3) = 0                   'These are the coordinates of the
LBWF.AxesWorldY(3) = LBWF.AxesLength(1)  'endpoint of the Y-axis
LBWF.AxesWorldZ(3) = 0
 
LBWF.AxesWorldX(4) = 0                   'These are the coordinates of the
LBWF.AxesWorldY(4) = 0                   'endpoint of the Z-axis
LBWF.AxesWorldZ(4) = LBWF.AxesLength(1)  '

 
 
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ObjectAssignCustomType(ObjectName$, CustomType$)
 
    ObjectToType = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToType = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    LBWF.ObjectType$(ObjectToType) = CustomType$
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''    
Function FF.LBWF.HideObjectsOfType(ObjectType$)
 
    'In version 0.6 of the library, this function presumes
    'that the programmer has passed a legitimate type
    'as an argument in the function.
    
    'Examine the types of all current objects.
    'If an object's type matches the type identified
    'in the argument of the function, then set the visibility
    'of that object to "hidden"
    
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        if (LBWF.ObjectType$(i) = ObjectType$) then
            LBWF.ObjectVisible(i) = 0
        end if 
    next i
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowObjectsOfType(ObjectType$)
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        if (LBWF.ObjectType$(i) = ObjectType$) then
            LBWF.ObjectVisible(i) = 1
        end if 
    next i
 
End function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.TranslateObjectsOfType(ObjectType$, transX, transY, transZ)
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        if (LBWF.ObjectType$(i) = ObjectType$) then
 
            FirstNode = LBWF.ObjectFirstNode(i)
            LastNode  = LBWF.ObjectLastNode(i)
 
            for j = FirstNode to LastNode
                LBWF.NodeWX(j) = LBWF.NodeWX(j) + transX
                LBWF.NodeWY(j) = LBWF.NodeWY(j) + transY
                LBWF.NodeWZ(j) = LBWF.NodeWZ(j) + transZ
            next j
 
            LBWF.ObjectCenterX(i) = LBWF.ObjectCenterX(i) + transX
            LBWF.ObjectCenterY(i) = LBWF.ObjectCenterY(i) + transY
            LBWF.ObjectCenterZ(i) = LBWF.ObjectCenterZ(i) + transZ
 
        end if 
    next i
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'dim LBWF.ObjectCenterX(i)
'dim LBWF.ObjectCenterY(i)
'dim LBWF.ObjectCenterZ(i)

'dim LBWF.NodeWX(i)
'dim LBWF.NodeWY(i)
'dim LBWF.NodeWZ(i)

 
'dim LBWF.ObjectFirstNode(i)
'dim LBWF.ObjectLastNode(i)
'dim LBWF.ObjectVisible(LBWF.ObjectResources(1))
'dim LBWF.ObjectLineThickness(LBWF.ObjectResources(1))
'dim LBWF.ObjectType$(LBWF.ObjectResources(1))    
    
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateLine(LineName$, x1, y1, z1, x2, y2, z2, LineColor$)
 
    NC = LBWF.NodeCount(1)
    LC = LBWF.LineCount(1)
 
    'Identify the two new nodes...
    LBWF.NodeWX(NC + 1) = x1
    LBWF.NodeWY(NC + 1) = y1
    LBWF.NodeWZ(NC + 1) = z1
 
    LBWF.NodeWX(NC + 2) = x2
    LBWF.NodeWY(NC + 2) = y2
    LBWF.NodeWZ(NC + 2) = z2
 
    'Identify the one new line...
    LBWF.LineInode(LC + 1) = (NC + 1)
    LBWF.LineJnode(LC + 1) = (NC + 2)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = LineName$
    LBWF.ObjectColor$(OC + 1)        = LineColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + 2)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + 1)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "line"
    LBWF.ObjectCenterX(OC + 1)       = (x1 + x2)/2
    LBWF.ObjectCenterY(OC + 1)       = (y1 + y2)/2
    LBWF.ObjectCenterZ(OC + 1)       = (z1 + z2)/2
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 2
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 1
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateDome(DomeName$, radius, numSides, DomeColor$)
 
    'Define the new nodes for this dome...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    NNDN = 3*numSides + 1    'Number of new dome nodes
    NNDL = 6*numSides        'Number of new dome lines

    'Find the coordinates of all the nodes on the base
    'layer of the dome...
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    'Find the coordinates of all the nodes on the SECOND
    'layer of the dome.
    NC1 = NC + numSides
    for i = 1 to numSides
        LBWF.NodeWX(NC1 + i) = 0.866*radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC1 + i) = 0.5*radius
        LBWF.NodeWZ(NC1 + i) = 0.866*radius*sin((i-1)*wedgeAngle)
    next i
 
    'Find the coordinates of all the nodes on the THIRD
    'layer of the dome.
    NC2 = NC1 + numSides
    for i = 1 to numSides
        LBWF.NodeWX(NC2 + i) = 0.500*radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC2 + i) = 0.866*radius
        LBWF.NodeWZ(NC2 + i) = 0.500*radius*sin((i-1)*wedgeAngle)
    next i
 
    'Identify the coordinate of the top-most node of the dome...
    LBWF.NodeWX(NC + 3*numSides + 1) = 0
    LBWF.NodeWY(NC + 3*numSides + 1) = radius
    LBWF.NodeWZ(NC + 3*numSides + 1) = 0
 
    'Define the new lines for this dome...
    LC = LBWF.LineCount(1)
 
    'These are the lines for the base layer of the dome...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the lines which connect the SECOND
    'layer of nodes...
    
    LC1 = LC + numSides
    NC1 = NC + numSides
 
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC1 + i) = (NC1 + i)
        LBWF.LineJnode(LC1 + i) = (NC1 + i + 1)
    next i
 
    LBWF.LineInode(LC1 + numSides) = (NC1 + numSides)
    LBWF.LineJnode(LC1 + numSides) = (NC1 + 1)
 
    'These are the lines which connect the THIRD
    'layer of nodes...
    
    LC2 = LC1 + numSides
    NC2 = NC1 + numSides
 
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC2 + i) = (NC2 + i)
        LBWF.LineJnode(LC2 + i) = (NC2 + i + 1)
    next i
 
    LBWF.LineInode(LC2 + numSides) = (NC2 + numSides)
    LBWF.LineJnode(LC2 + numSides) = (NC2 + 1)
 
    'These are the lines which connect the BASE layer
    'of nodes to the SECOND layer of nodes...
    
    LC3 = LC2 + numSides
 
    for i = 1 to numSides
        LBWF.LineInode(LC3 + i) = (NC + i)
        LBWF.LineJnode(LC3 + i) = (NC1 + i)
    next i
 
    'These are the lines which connect the SECOND layer
    'of nodes to the THIRD layer of nodes...
    
    LC4 = LC3 + numSides
 
    for i = 1 to numSides
        LBWF.LineInode(LC4 + i) = (NC1 + i)
        LBWF.LineJnode(LC4 + i) = (NC2 + i)
    next i
 
    'These are the lines which connect the THIRD layer
    'of nodes to the TOP-MOST node...
    
    LC5 = LC4 + numSides
 
    for i = 1 to numSides
        LBWF.LineInode(LC5 + i) = (NC2 + i)
        LBWF.LineJnode(LC5 + i) = (NC + NNDN)   'NNDN is the last node of the dome...
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = DomeName$
    LBWF.ObjectColor$(OC + 1)        = DomeColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + NNDN)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + NNDL)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "dome"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = radius/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + NNDN
    LBWF.LineCount(1)   = LBWF.LineCount(1) + NNDL
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
end function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.PauseUsingTimer(DelayMS)
 
    Timer DelayMS, [End.Of.Delay]
    Wait
    [End.Of.Delay]
    Timer 0
 
End Function
 
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.PauseMilliseconds(DelayMS)
 
    StartingTimeMS = time$("ms")
 
    ElapsedTimeMS = 0
 
    While (ElapsedTimeMS <= DelayMS)
        'Keep checking the elapsed time until the 
        'elapsed time is greater than the delay time
        'as contained in the variable DelayMS
        CurrentTimeMS = time$("ms")
        ElapsedTimeMS = CurrentTimeMS - StartingTimeMS
    Wend
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.About()
 
    Notice "Liberty BASIC Wireframe Library          " + chr$(13) + _
           "                                         " + chr$(13) + _
           "Library Version " + LBWF.VersionNumber$(1) + chr$(13) + _
           "                                         " + chr$(13) + _
           "by Tomas J. Nally                        "
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.LBWFVersion$()
 
    FF.LBWF.LBWFVersion$ = LBWF.VersionNumber$(1)
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ObjectSetColor(ObjectName$, NewColor$)
 
    'Determine the object whose color will
    'change by comparing the name of the object
    'against a list of all object names...
    
    ObjectToChangeColor = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToChangeColor = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Now that the object has been identified,
    'change its color property...
    
    LBWF.ObjectColor$(ObjectToChangeColor) = NewColor$
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ObjectSetLineThickness(ObjectName$, LineThickness)
 
    'Determine the object whose line thickness will
    'change by comparing the name of the object
    'against a list of all object names...
    
    ObjectToChange = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToChange = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Now that the object has been identified,
    'change its line thickness property...
    
    LBWF.ObjectLineThickness(ObjectToChange) = LineThickness
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.SetAxesProperties(AxesLength, AxesThickness)
 
    LBWF.AxesLength(1) = AxesLength
    LBWF.AxesWorldX(2) = LBWF.AxesLength(1)
    LBWF.AxesWorldY(3) = LBWF.AxesLength(1)
    LBWF.AxesWorldZ(4) = LBWF.AxesLength(1)
 
    LBWF.AxesLineThickness(1) = AxesThickness
 
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowAxes()
 
    LBWF.AxesVisible(1) = 1
 
End function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.HideAxes()
 
    LBWF.AxesVisible(1) = 0
 
End function
 
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowObject(ObjectName$)
 
    'Determine the object to be hidden by comparing the name
    'argument against a list of object names...
    
    ObjectToShow = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToShow = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Set the visible property of that object to 1...
    LBWF.ObjectVisible(ObjectToShow) = 1
 
end Function
 
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.HideObject(ObjectName$)
 
    'Determine the object to be hidden by comparing the name
    'argument against a list of object names...
    
    ObjectToHide = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToHide = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    'Set the visible property of that object to zero...
    LBWF.ObjectVisible(ObjectToHide) = 0
 
end Function
 
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.PointCameraAtObject(ObjectName$)
 
    'Find the geometric center of the object identified
    'as the argument above...
    
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    ObjectCenterX = val(word$(ObjectCenter$, 1))
    ObjectCenterY = val(word$(ObjectCenter$, 2))
    ObjectCenterZ = val(word$(ObjectCenter$, 3))
 
    'Now, point the camera to the x, y and z coordinates
    'identified above...
    
    AAA = FF.LBWF.ViewingCenter(ObjectCenterX, ObjectCenterY, ObjectCenterZ)
 
End Function
 
 
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateGridObject(GridName$, NumUnitsXdirection, NumUnitsZdirection, UnitSize, GridColor$)
 
    NumGridNodes = 2*(NumUnitsXdirection + 1) + 2*(NumUnitsZdirection + 1)
    NumGridLines = (NumUnitsXdirection + 1) + (NumUnitsZdirection + 1)
 
    TotalGridLengthX = NumUnitsXdirection * UnitSize
    TotalGridWidthZ  = NumUnitsZdirection * UnitSize
 
    UpperLeftCornerX = (0 - TotalGridLengthX/2)
    UpperLeftCornerZ = (0 - TotalGridWidthZ/2)
 
    LowerRightCornerX = TotalGridLengthX/2
    LowerRightCornerZ = TotalGridWidthZ/2
 
    NC = LBWF.NodeCount(1)
    LC = LBWF.LineCount(1)
 
    'Define all of the nodes which connect the lines parallel to 
    'the z-axis...
    
    for i = 1 to (NumUnitsXdirection + 1)
        LBWF.NodeWX(NC + i) = UpperLeftCornerX + (i-1)*UnitSize
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = UpperLeftCornerZ
    next i
 
    Na = NC + NumUnitsXdirection + 1
 
    for i = 1 to (NumUnitsXdirection + 1)
        LBWF.NodeWX(Na + i) = UpperLeftCornerX + (i-1)*UnitSize
        LBWF.NodeWY(Na + i) = 0
        LBWF.NodeWZ(Na + i) = LowerRightCornerZ
    next i
 
    'Define all of the nodes which connect the lines parallel to
    'the x-axis...
    
    Nb = NC + 2*(NumUnitsXdirection + 1)
 
    for i = 1 to (NumUnitsZdirection + 1)
        LBWF.NodeWX(Nb + i) = UpperLeftCornerX
        LBWF.NodeWY(Nb + i) = 0
        LBWF.NodeWZ(Nb + i) = UpperLeftCornerZ + (i-1)*UnitSize
    next i
 
    Nd = NC + 2*(NumUnitsXdirection + 1) + (NumUnitsZdirection + 1)
 
    for i = 1 to (NumUnitsZdirection + 1)
        LBWF.NodeWX(Nd + i) = LowerRightCornerX
        LBWF.NodeWY(Nd + i) = 0
        LBWF.NodeWZ(Nd + i) = UpperLeftCornerZ + (i-1)*UnitSize
    next i
 
    'Define the i-nodes and j-nodes for the (NumUnitsXdirection + 1) lines
    'that run parallel to the z-axis...
    
    for i = 1 to (NumUnitsXdirection + 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + (NumUnitsXdirection + 1) + i)
    next i
 
    'Define the i-nodes and j-nodes for the (NumUnitsZdirection + 1) lines
    'that run parallel to the x-axis...

    LCa = LC + (NumUnitsXdirection + 1)
 
    for i = 1 to (NumUnitsZdirection + 1)
        LBWF.LineInode(LCa + i) = (NC + 2*(NumUnitsXdirection + 1) + i)
        LBWF.LineJnode(LCa + i) = LBWF.LineInode(LCa + i) + (NumUnitsZdirection + 1)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = GridName$
    LBWF.ObjectColor$(OC + 1)        = GridColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + NumGridNodes)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + NumGridLines)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "grid"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = 0
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + NumGridNodes
    LBWF.LineCount(1)   = LBWF.LineCount(1) + NumGridLines
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreateCone(ConeName$, radius, numSides, coneheight, ConeColor$)
 
    'Define the new nodes for this cone...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    LBWF.NodeWX(NC + numSides + 1) = 0
    LBWF.NodeWY(NC + numSides + 1) = coneheight
    LBWF.NodeWZ(NC + numSides + 1) = 0
 
 
    'Define the new lines for this cone...
    LC = LBWF.LineCount(1)
 
    'These are the new lines for the bottom face of the cone...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the lines for the sides of the cone which
    'go from the base up to the peak of the cone...
    
    for i = 1 to numSides
        LBWF.LineInode(LC + numSides + i) = (NC + i)
        LBWF.LineJnode(LC + numSides + i) = (NC + numSides + 1)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)         = ConeName$
    LBWF.ObjectColor$(OC + 1)        = ConeColor$
    LBWF.ObjectFirstNode(OC + 1)     = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)      = (NC + numSides + 1)
    LBWF.ObjectFirstLine(OC + 1)     = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)      = (LC + 2*numSides)
    LBWF.ObjectVisible(OC + 1)       = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)         = "cone"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = coneheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + numSides + 1
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 2*numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreatePyramid(pyrName$, xdim, zdim, pyrheight, pyrColor$)
 
    'Define the 5 new nodes for this pyramid...
    NC = LBWF.NodeCount(1)
 
    LBWF.NodeWX(NC + 1) = xdim/2      : LBWF.NodeWY(NC + 1) = 0 : LBWF.NodeWZ(NC + 1) = (-1)*zdim/2
    LBWF.NodeWX(NC + 2) = xdim/2      : LBWF.NodeWY(NC + 2) = 0 : LBWF.NodeWZ(NC + 2) = zdim/2
    LBWF.NodeWX(NC + 3) = (-1)*xdim/2 : LBWF.NodeWY(NC + 3) = 0 : LBWF.NodeWZ(NC + 3) = zdim/2
    LBWF.NodeWX(NC + 4) = (-1)*xdim/2 : LBWF.NodeWY(NC + 4) = 0 : LBWF.NodeWZ(NC + 4) = (-1)*zdim/2
 
    LBWF.NodeWX(NC + 5) = 0 
    LBWF.NodeWY(NC + 5) = pyrheight 
    LBWF.NodeWZ(NC + 5) = 0
 
    'Define the 8 new lines for this pyramid...
    LC = LBWF.LineCount(1)
 
    LBWF.LineInode(LC + 1) = (NC + 1) : LBWF.LineJnode(LC + 1) = (NC + 2)
    LBWF.LineInode(LC + 2) = (NC + 2) : LBWF.LineJnode(LC + 2) = (NC + 3)
    LBWF.LineInode(LC + 3) = (NC + 3) : LBWF.LineJnode(LC + 3) = (NC + 4)
    LBWF.LineInode(LC + 4) = (NC + 4) : LBWF.LineJnode(LC + 4) = (NC + 1)
 
    LBWF.LineInode(LC + 5) = (NC + 1) : LBWF.LineJnode(LC + 5) = (NC + 5)
    LBWF.LineInode(LC + 6) = (NC + 2) : LBWF.LineJnode(LC + 6) = (NC + 5)
    LBWF.LineInode(LC + 7) = (NC + 3) : LBWF.LineJnode(LC + 7) = (NC + 5)
    LBWF.LineInode(LC + 8) = (NC + 4) : LBWF.LineJnode(LC + 8) = (NC + 5)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = pyrName$
    LBWF.ObjectColor$(OC + 1)    = pyrColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 5)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 8)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "pyramid"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = pyrheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 5
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 8
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
end Function
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.TranslateObject(ObjectName$, transX, transY, transZ)
 
    'Determine the object to be translated by comparing the name
    'argument against a list of object names...
    
    ObjectToTranslate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToTranslate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FirstNodeToMove = LBWF.ObjectFirstNode(ObjectToTranslate)
    LastNodeToMove  = LBWF.ObjectLastNode(ObjectToTranslate)
 
    for i = FirstNodeToMove to LastNodeToMove
        LBWF.NodeWX(i) = LBWF.NodeWX(i) + transX
        LBWF.NodeWY(i) = LBWF.NodeWY(i) + transY
        LBWF.NodeWZ(i) = LBWF.NodeWZ(i) + transZ
    next i
 
    'As of Library Version 0.6, the array variables
    'which hold the values of the geometric center
    'of the object must be adjusted also

    LBWF.ObjectCenterX(ObjectToTranslate) = LBWF.ObjectCenterX(ObjectToTranslate) + transX
    LBWF.ObjectCenterY(ObjectToTranslate) = LBWF.ObjectCenterY(ObjectToTranslate) + transY
    LBWF.ObjectCenterZ(ObjectToTranslate) = LBWF.ObjectCenterZ(ObjectToTranslate) + transZ
 
 
end Function
 
 
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreatePolygon(PolyName$, radius, numSides, PolyColor$)
 
    'Define the new nodes for this polygon...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    'Define the lines for this polygon...
    LC = LBWF.LineCount(1)
 
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = PolyName$
    LBWF.ObjectColor$(OC + 1)    = PolyColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + numSides)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + numSides)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "polygon"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = 0
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + numSides
    LBWF.LineCount(1)   = LBWF.LineCount(1) + numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.CreateCyl2(Cyl2Name$, radiusBottum, radiusTop, numSides, cyl2height, Cyl2Color$)
 
    'Define the new nodes for this cyl2...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radiusBottum*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radiusBottum*sin((i-1)*wedgeAngle)
    next i
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + numSides + i) = radiusTop*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + numSides + i) = cyl2height
        LBWF.NodeWZ(NC + numSides + i) = radiusTop*sin((i-1)*wedgeAngle)
    next i
 
    'Define the new lines for this cyl2...
    
    LC = LBWF.LineCount(1)
 
    'These are the new lines for the bottom face of the cyl2...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the new lines for the top face of the cyl2...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + numSides + i) = (NC + numSides + i)
        LBWF.LineJnode(LC + numSides + i) = (NC + numSides + i + 1)
    next i
 
    LBWF.LineInode(LC + 2*numSides) = (NC + 2*numSides)
    LBWF.LineJnode(LC + 2*numSides) = (NC + numSides + 1)
 
    'These are the side lines of the cyl2...
    
    for i = 1 to numSides
        LBWF.LineInode(LC + 2*numSides + i) = (NC + i)
        LBWF.LineJnode(LC + 2*numSides + i) = (NC + numSides + i)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = Cyl2Name$
    LBWF.ObjectColor$(OC + 1)    = Cyl2Color$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 2*numSides)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 3*numSides)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "cyl2"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = cyl2height/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 2*numSides
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 3*numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''

 
Function FF.LBWF.CreateCylinder(ObjectName$, radius, numSides, cylheight, ObjectColor$)
 
    'Define the new nodes for this cylinder...
    NC = LBWF.NodeCount(1)
    pi = 3.14159
    wedgeAngle = (2*pi)/numSides
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + i) = 0
        LBWF.NodeWZ(NC + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    for i = 1 to numSides
        LBWF.NodeWX(NC + numSides + i) = radius*cos((i-1)*wedgeAngle)
        LBWF.NodeWY(NC + numSides + i) = cylheight
        LBWF.NodeWZ(NC + numSides + i) = radius*sin((i-1)*wedgeAngle)
    next i
 
    'Define the new lines for this cylinder...
    
    LC = LBWF.LineCount(1)
 
    'These are the new lines for the bottom face of the cylinder...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + i) = (NC + i)
        LBWF.LineJnode(LC + i) = (NC + i + 1)
    next i
 
    LBWF.LineInode(LC + numSides) = (NC + numSides)
    LBWF.LineJnode(LC + numSides) = (NC + 1)
 
    'These are the new lines for the top face of the cylinder...
    for i = 1 to (numSides - 1)
        LBWF.LineInode(LC + numSides + i) = (NC + numSides + i)
        LBWF.LineJnode(LC + numSides + i) = (NC + numSides + i + 1)
    next i
 
    LBWF.LineInode(LC + 2*numSides) = (NC + 2*numSides)
    LBWF.LineJnode(LC + 2*numSides) = (NC + numSides + 1)
 
    'These are the side lines of the cylinder...
    
    for i = 1 to numSides
        LBWF.LineInode(LC + 2*numSides + i) = (NC + i)
        LBWF.LineJnode(LC + 2*numSides + i) = (NC + numSides + i)
    next i
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = ObjectName$
    LBWF.ObjectColor$(OC + 1)    = ObjectColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 2*numSides)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 3*numSides)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "cylinder"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = cylheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 2*numSides
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 3*numSides
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
end Function
 
''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CreateBox(ObjectName$, xdim, zdim, boxheight, ObjectColor$)
 
    'Define the 8 new nodes for this box...
    NC = LBWF.NodeCount(1)
    BH = boxheight
 
    LBWF.NodeWX(NC + 1) = xdim/2      : LBWF.NodeWY(NC + 1) = 0 : LBWF.NodeWZ(NC + 1) = (-1)*zdim/2
    LBWF.NodeWX(NC + 2) = xdim/2      : LBWF.NodeWY(NC + 2) = 0 : LBWF.NodeWZ(NC + 2) = zdim/2
    LBWF.NodeWX(NC + 3) = (-1)*xdim/2 : LBWF.NodeWY(NC + 3) = 0 : LBWF.NodeWZ(NC + 3) = zdim/2
    LBWF.NodeWX(NC + 4) = (-1)*xdim/2 : LBWF.NodeWY(NC + 4) = 0 : LBWF.NodeWZ(NC + 4) = (-1)*zdim/2
 
    LBWF.NodeWX(NC + 5) = xdim/2      : LBWF.NodeWY(NC + 5) = BH : LBWF.NodeWZ(NC + 5) = (-1)*zdim/2
    LBWF.NodeWX(NC + 6) = xdim/2      : LBWF.NodeWY(NC + 6) = BH : LBWF.NodeWZ(NC + 6) = zdim/2
    LBWF.NodeWX(NC + 7) = (-1)*xdim/2 : LBWF.NodeWY(NC + 7) = BH : LBWF.NodeWZ(NC + 7) = zdim/2
    LBWF.NodeWX(NC + 8) = (-1)*xdim/2 : LBWF.NodeWY(NC + 8) = BH : LBWF.NodeWZ(NC + 8) = (-1)*zdim/2
 
 
    'Define 12 new lines for this box...
    LC = LBWF.LineCount(1)
 
    LBWF.LineInode(LC + 1) = (NC + 1) : LBWF.LineJnode(LC + 1) = (NC + 2)
    LBWF.LineInode(LC + 2) = (NC + 2) : LBWF.LineJnode(LC + 2) = (NC + 3)
    LBWF.LineInode(LC + 3) = (NC + 3) : LBWF.LineJnode(LC + 3) = (NC + 4)
    LBWF.LineInode(LC + 4) = (NC + 4) : LBWF.LineJnode(LC + 4) = (NC + 1)
 
    LBWF.LineInode(LC + 5) = (NC + 1) : LBWF.LineJnode(LC + 5) = (NC + 5)
    LBWF.LineInode(LC + 6) = (NC + 2) : LBWF.LineJnode(LC + 6) = (NC + 6)
    LBWF.LineInode(LC + 7) = (NC + 3) : LBWF.LineJnode(LC + 7) = (NC + 7)
    LBWF.LineInode(LC + 8) = (NC + 4) : LBWF.LineJnode(LC + 8) = (NC + 8)
 
    LBWF.LineInode(LC + 9)  = (NC + 5) : LBWF.LineJnode(LC + 9)  = (NC + 6)
    LBWF.LineInode(LC + 10) = (NC + 6) : LBWF.LineJnode(LC + 10) = (NC + 7)
    LBWF.LineInode(LC + 11) = (NC + 7) : LBWF.LineJnode(LC + 11) = (NC + 8)
    LBWF.LineInode(LC + 12) = (NC + 8) : LBWF.LineJnode(LC + 12) = (NC + 5)
 
    'Define other object properties
    OC = LBWF.ObjectCount(1)
 
    LBWF.ObjectName$(OC + 1)     = ObjectName$
    LBWF.ObjectColor$(OC + 1)    = ObjectColor$
    LBWF.ObjectFirstNode(OC + 1) = (NC + 1)
    LBWF.ObjectLastNode(OC + 1)  = (NC + 8)
    LBWF.ObjectFirstLine(OC + 1) = (LC + 1)
    LBWF.ObjectLastLine(OC + 1)  = (LC + 12)
    LBWF.ObjectVisible(OC + 1)   = 1
    LBWF.ObjectLineThickness(OC + 1) = 1
    LBWF.ObjectType$(OC + 1)     = "box"
    LBWF.ObjectCenterX(OC + 1)       = 0
    LBWF.ObjectCenterY(OC + 1)       = boxheight/2
    LBWF.ObjectCenterZ(OC + 1)       = 0
 
    'Update the node count, the line count, and the object count...

    LBWF.NodeCount(1)   = LBWF.NodeCount(1) + 8
    LBWF.LineCount(1)   = LBWF.LineCount(1) + 12
    LBWF.ObjectCount(1) = LBWF.ObjectCount(1) + 1
 
 
    FF.LBWF.CreateBox = 0
 
end function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.CameraLocation(CamX, CamY, CamZ)
 
    LBWF.CamX(1) = CamX
    LBWF.CamY(1) = CamY
    LBWF.CamZ(1) = CamZ
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ViewingCenter(VCtrX, VCtrY, VCtrZ)
 
    LBWF.VCtrX(1) = VCtrX
    LBWF.VCtrY(1) = VCtrY
    LBWF.VCtrZ(1) = VCtrZ
 
End Function
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ZoomFactor(ZoomFac)
 
    LBWF.ZoomFac(1) = ZoomFac
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.Camera(CamX, CamY, CamZ, VCtrX, VCtrY, VCtrZ, ZoomFac)
 
    LBWF.CamX(1) = CamX
    LBWF.CamY(1) = CamY
    LBWF.CamZ(1) = CamZ
    LBWF.VCtrX(1) = VCtrX
    LBWF.VCtrY(1) = VCtrY
    LBWF.VCtrZ(1) = VCtrZ
    LBWF.ZoomFac(1) = ZoomFac
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ScreenCenter(ScrCenterX, ScrCenterY)
 
    LBWF.ScrCenterX(1) = ScrCenterX
    LBWF.ScrCenterY(1) = ScrCenterY
 
end Function
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.BackGroundColor(BGColor$)
 
    LBWF.BackGroundColor$(1) = BGColor$
 
end Function
 
 
'''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ClearGraphicScreen()
 
    print #main.wfscene, "cls"
    print #main.wfscene, "fill "; LBWF.BackGroundColor$(1)
 
end Function
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.DrawObjectsOfType(ObjectType$)
 
    OC = LBWF.ObjectCount(1)
 
    for q = 1 to OC
 
        if (LBWF.ObjectType$(q) = ObjectType$) then
 
            ObjectToDraw = q
 
            FirstNodeOfObject = LBWF.ObjectFirstNode(ObjectToDraw)
            LastNodeOfObject  = LBWF.ObjectLastNode(ObjectToDraw)
            FirstLineOfObject = LBWF.ObjectFirstLine(ObjectToDraw)
            LastLineOfObject  = LBWF.ObjectLastLine(ObjectToDraw)
 
            'The documentation for this elaborate procedure will
            'not be contained herein.  To see the documentation,
            'visit the function FF.LBWF.DrawAllObjects()

            Cam2CtrX = (LBWF.VCtrX(1) - LBWF.CamX(1))
            Cam2CtrY = (LBWF.VCtrY(1) - LBWF.CamY(1))
            Cam2CtrZ = (LBWF.VCtrZ(1) - LBWF.CamZ(1))
 
            LenCam2Ctr = sqr(Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2)
 
            virtualXi = (-1)*(Cam2CtrZ)
            virtualXj = 0
            virtualXk = Cam2CtrX
 
            LenVirtualX = sqr(virtualXi^2 + virtualXj^2 + virtualXk^2)
            virtualXi = virtualXi / LenVirtualX
            virtualXj = virtualXj / LenVirtualX
            virtualXk = virtualXk / LenVirtualX
 
            virtualYi = (-1)*(virtualXk * Cam2CtrY)
            virtualYj = (virtualXk * Cam2CtrX) - (virtualXi * Cam2CtrZ)
            virtualYk = (virtualXi * Cam2CtrY)
 
            LenVirtualY = sqr(virtualYi^2 + virtualYj^2 + virtualYk^2)
            virtualYi = virtualYi / LenVirtualY
            virtualYj = virtualYj / LenVirtualY
            virtualYk = virtualYk / LenVirtualY
 
            virtualXi = virtualXi / LenCam2Ctr
            virtualXj = virtualXj / LenCam2Ctr
            virtualXk = virtualXk / LenCam2Ctr
 
            virtualYi = virtualYi / LenCam2Ctr
            virtualYj = virtualYj / LenCam2Ctr
            virtualYk = virtualYk / LenCam2Ctr
 
            '''''''''''''''''''''''''''''''''''''''''''''''
            'FIND SCREEN COORDINATES OF OBJECT NODES
            '''''''''''''''''''''''''''''''''''''''''''''''
    
            for i = FirstNodeOfObject to LastNodeOfObject
 
                'Establish the vector components of the Camera-to-Node Vector
                Cam2NodeX = (LBWF.NodeWX(i) - LBWF.CamX(1))
                Cam2NodeY = (LBWF.NodeWY(i) - LBWF.CamY(1))
                Cam2NodeZ = (LBWF.NodeWZ(i) - LBWF.CamZ(1))
 
                numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
                denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
                t = (numerator / denominator)
 
                ipX = LBWF.CamX(1) + Cam2NodeX*t
                ipY = LBWF.CamY(1) + Cam2NodeY*t
                ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
                Ctr2ipX = (ipX - LBWF.VCtrX(1))
                Ctr2ipY = (ipY - LBWF.VCtrY(1))
                Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
                PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
                SCM = 500   'Note: SCM is an acronym for "Secondary Scale Multiplier".
                            '      This value was found by experimentation when it was
                            '      observed that the Scale factor by itself was
                            '      too small without a multiplier.

                LBWF.NodeSX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
                PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
                LBWF.NodeSY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
            next i
 
            'With the the screen coordinates of the nodes determined,
            'it is time to draw each line of the object...

                'Set the drawing color for the object...
                DrawingColor$ = LBWF.ObjectColor$(ObjectToDraw)
                print #main.wfscene, "color "; DrawingColor$
 
                'Set the line thickness for the object...
                LineThickness = LBWF.ObjectLineThickness(ObjectToDraw)
                print #main.wfscene, "size "; LineThickness
 
                for i = FirstLineOfObject to LastLineOfObject
                    x1 = LBWF.NodeSX(LBWF.LineInode(i))
                    y1 = LBWF.NodeSY(LBWF.LineInode(i))
                    x2 = LBWF.NodeSX(LBWF.LineJnode(i))
                    y2 = LBWF.NodeSY(LBWF.LineJnode(i))
 
                    print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
                next i
 
        end if
 
    next q
 
    'Reset the default line thickness back to 1...
    print #main.wfscene, "size 1" 
 
    'Set the default drawing color back to black...
    print #main.wfscene, "color black"
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.DrawObject(ObjectName$)
 
    ObjectToDraw = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToDraw = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FirstNodeOfObject = LBWF.ObjectFirstNode(ObjectToDraw)
    LastNodeOfObject  = LBWF.ObjectLastNode(ObjectToDraw)
    FirstLineOfObject = LBWF.ObjectFirstLine(ObjectToDraw)
    LastLineOfObject  = LBWF.ObjectLastLine(ObjectToDraw)
 
    'The documentation for this elaborate procedure will
    'not be contained herein.  To see the documentation,
    'visit the function FF.LBWF.DrawAllObjects()

    Cam2CtrX = (LBWF.VCtrX(1) - LBWF.CamX(1))
    Cam2CtrY = (LBWF.VCtrY(1) - LBWF.CamY(1))
    Cam2CtrZ = (LBWF.VCtrZ(1) - LBWF.CamZ(1))
 
    LenCam2Ctr = sqr(Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2)
 
    virtualXi = (-1)*(Cam2CtrZ)
    virtualXj = 0
    virtualXk = Cam2CtrX
 
    LenVirtualX = sqr(virtualXi^2 + virtualXj^2 + virtualXk^2)
    virtualXi = virtualXi / LenVirtualX
    virtualXj = virtualXj / LenVirtualX
    virtualXk = virtualXk / LenVirtualX
 
    virtualYi = (-1)*(virtualXk * Cam2CtrY)
    virtualYj = (virtualXk * Cam2CtrX) - (virtualXi * Cam2CtrZ)
    virtualYk = (virtualXi * Cam2CtrY)
 
    LenVirtualY = sqr(virtualYi^2 + virtualYj^2 + virtualYk^2)
    virtualYi = virtualYi / LenVirtualY
    virtualYj = virtualYj / LenVirtualY
    virtualYk = virtualYk / LenVirtualY
 
    virtualXi = virtualXi / LenCam2Ctr
    virtualXj = virtualXj / LenCam2Ctr
    virtualXk = virtualXk / LenCam2Ctr
 
    virtualYi = virtualYi / LenCam2Ctr
    virtualYj = virtualYj / LenCam2Ctr
    virtualYk = virtualYk / LenCam2Ctr
 
    '''''''''''''''''''''''''''''''''''''''''''''''
    'FIND SCREEN COORDINATES OF OBJECT NODES
    '''''''''''''''''''''''''''''''''''''''''''''''
    
    for i = FirstNodeOfObject to LastNodeOfObject
 
        'Establish the vector components of the Camera-to-Node Vector
        Cam2NodeX = (LBWF.NodeWX(i) - LBWF.CamX(1))
        Cam2NodeY = (LBWF.NodeWY(i) - LBWF.CamY(1))
        Cam2NodeZ = (LBWF.NodeWZ(i) - LBWF.CamZ(1))
 
        numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
        denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
        t = (numerator / denominator)
 
        ipX = LBWF.CamX(1) + Cam2NodeX*t
        ipY = LBWF.CamY(1) + Cam2NodeY*t
        ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
        Ctr2ipX = (ipX - LBWF.VCtrX(1))
        Ctr2ipY = (ipY - LBWF.VCtrY(1))
        Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
        PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
        SCM = 500   'Note: SCM is an acronym for "Secondary Scale Multiplier".
                    '      This value was found by experimentation when it was
                    '      observed that the Scale factor by itself was
                    '      too small without a multiplier.

        LBWF.NodeSX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
        PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
        LBWF.NodeSY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
    next i
 
    'With the the screen coordinates of the nodes determined,
    'it is time to draw each line of the object...

        'Set the drawing color for the object...
        DrawingColor$ = LBWF.ObjectColor$(ObjectToDraw)
        print #main.wfscene, "color "; DrawingColor$
 
        'Set the line thickness for the object...
        LineThickness = LBWF.ObjectLineThickness(ObjectToDraw)
        print #main.wfscene, "size "; LineThickness
 
        for i = FirstLineOfObject to LastLineOfObject
            x1 = LBWF.NodeSX(LBWF.LineInode(i))
            y1 = LBWF.NodeSY(LBWF.LineInode(i))
            x2 = LBWF.NodeSX(LBWF.LineJnode(i))
            y2 = LBWF.NodeSY(LBWF.LineJnode(i))
 
            print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
        next i
 
    'Reset the default line thickness back to 1...
    print #main.wfscene, "size 1" 
 
    'Set the default drawing color back to black...
    print #main.wfscene, "color black"
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.DrawAllObjects()
 
    'Find the camera-to-viewing-center vector...

    Cam2CtrX = (LBWF.VCtrX(1) - LBWF.CamX(1))
    Cam2CtrY = (LBWF.VCtrY(1) - LBWF.CamY(1))
    Cam2CtrZ = (LBWF.VCtrZ(1) - LBWF.CamZ(1))
 
    'Length of the camera-to-viewing-center vector...

    LenCam2Ctr = sqr(Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2)
 
    'The vector equation for the virtual image plane can be written
    'as follows:
    '
    'Cam2CtrX*(x - CtrX) + Cam2CtrY*(y - CtrY) + Cam2CtrZ*(z - CtrZ) = 0

    'Imagine a unit vector pointing in the -Y direction.  The
    'components of this vector are 0i -1j + 0k.  When we take
    'the cross product of this vector with the Camera-to-Center
    'vector, the result is the virtual x-axis vector imposed
    'upon the virtual image plane.  These are the vector
    'components of the virtual x-axis vector.

    virtualXi = (-1)*(Cam2CtrZ)
    virtualXj = 0
    virtualXk = Cam2CtrX
 
    'Find the length of this vector, then divide components
    'by this length.

    LenVirtualX = sqr(virtualXi^2 + virtualXj^2 + virtualXk^2)
    virtualXi = virtualXi / LenVirtualX
    virtualXj = virtualXj / LenVirtualX
    virtualXk = virtualXk / LenVirtualX
 
 
    'In order to find the virtual y-axis on the image plane,
    'we need to take the cross product of the virtual x-axis
    'vector with the Camera-to-Center Vector.  Given below is
    'the result of that cross product.

    virtualYi = (-1)*(virtualXk * Cam2CtrY)
    virtualYj = (virtualXk * Cam2CtrX) - (virtualXi * Cam2CtrZ)
    virtualYk = (virtualXi * Cam2CtrY)
 
    'Find the length of this vector, then divide the
    'components by this length

    LenVirtualY = sqr(virtualYi^2 + virtualYj^2 + virtualYk^2)
    virtualYi = virtualYi / LenVirtualY
    virtualYj = virtualYj / LenVirtualY
    virtualYk = virtualYk / LenVirtualY
 
    'Divide the unit virtual X-axis vector and the
    'virtual Y-axis vector by LenCam2Ctr.  This transformation
    'of these two vectors will allow the objects to get
    'smaller as the camera moves away from the viewing
    'center, or get larger as the camera moves toward
    'the viewing center.

    virtualXi = virtualXi / LenCam2Ctr
    virtualXj = virtualXj / LenCam2Ctr
    virtualXk = virtualXk / LenCam2Ctr
 
    virtualYi = virtualYi / LenCam2Ctr
    virtualYj = virtualYj / LenCam2Ctr
    virtualYk = virtualYk / LenCam2Ctr
 
    '''''''''''''''''''''''''''''''''''''''''''''''
    'OBJECT NODES *** OBJECT NODES *** OBJECT NODES
    '''''''''''''''''''''''''''''''''''''''''''''''
    'For each and every node in every object,
    'find the screen coordinates

    for i = 1 to LBWF.NodeCount(1)
 
        'Establish the vector components of the Camera-to-Node Vector
        Cam2NodeX = (LBWF.NodeWX(i) - LBWF.CamX(1))
        Cam2NodeY = (LBWF.NodeWY(i) - LBWF.CamY(1))
        Cam2NodeZ = (LBWF.NodeWZ(i) - LBWF.CamZ(1))
 
        'The parametric equations for the Camera-to-Node Vector
        'can be written as follows:
        '
        'x = CamX + Cam2NodeX*t
        'y = CamY + Cam2NodeY*t
        'z = CamZ + Cam2NodeZ*t
        '
        'Plug these three equations into the vector equation
        'for the virtual image plane...
        '
        'Cam2CtrX*(x - CtrX) + Cam2CtrY*(y - CtrY) + Cam2CtrZ*(z - CtrZ) = 0
        '
        '...and then solve for t

        numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
        denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
        t = (numerator / denominator)
 
        'Having solved for t, determine the point in space
        '(ipx, ipy, ipz) where 'the Camera-to-Node vector intersects
        'the virtual image plane.

        ipX = LBWF.CamX(1) + Cam2NodeX*t
        ipY = LBWF.CamY(1) + Cam2NodeY*t
        ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
        'Establish the vector components of the vector from the
        'center to (ipx, ipy, ipz).

        Ctr2ipX = (ipX - LBWF.VCtrX(1))
        Ctr2ipY = (ipY - LBWF.VCtrY(1))
        Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
        'The projection of this vector along the virtual X-axis
        'is the dot product of this vector with the unit vector
        'along the virtual X-Axis"

        PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
        SCM = 500   'Note: SCM is an acronym for "Secondary Scale Multiplier".
                    '      This value was found by experimentation when it was
                    '      observed that the Scale factor by itself was
                    '      too small without a multiplier.

        LBWF.NodeSX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
        'The projection of this vector along the virtual Y-axis
        'is the dot product of this vector with the unit vector
        'along the virtual Y-Axis"

        PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
        LBWF.NodeSY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
    next i
 
    '''''''''''''''''''''''''''''''''''''''''
    'AXES NODES *** AXES NODES *** AXES NODES 
    '''''''''''''''''''''''''''''''''''''''''

    for i = 1 to 4
 
        'Establish the vector components of the Camera-to-Node Vector
        Cam2NodeX = (LBWF.AxesWorldX(i) - LBWF.CamX(1))
        Cam2NodeY = (LBWF.AxesWorldY(i) - LBWF.CamY(1))
        Cam2NodeZ = (LBWF.AxesWorldZ(i) - LBWF.CamZ(1))
 
        numerator   = Cam2CtrX^2 + Cam2CtrY^2 + Cam2CtrZ^2
        denominator = (Cam2NodeX * Cam2CtrX) + (Cam2NodeY * Cam2CtrY) + (Cam2NodeZ * Cam2CtrZ)
        t = (numerator / denominator)
 
        ipX = LBWF.CamX(1) + Cam2NodeX*t
        ipY = LBWF.CamY(1) + Cam2NodeY*t
        ipZ = LBWF.CamZ(1) + Cam2NodeZ*t
 
        Ctr2ipX = (ipX - LBWF.VCtrX(1))
        Ctr2ipY = (ipY - LBWF.VCtrY(1))
        Ctr2ipZ = (ipZ - LBWF.VCtrZ(1))
 
        PX = (Ctr2ipX*virtualXi) + (Ctr2ipY*virtualXj) + (Ctr2ipZ*virtualXk)
 
        SCM = 500   
 
        LBWF.AxesScreenX(i) = LBWF.ScrCenterX(1) + (SCM*LBWF.ZoomFac(1) * PX)
 
        PY = (Ctr2ipX*virtualYi) + (Ctr2ipY*virtualYj) + (Ctr2ipZ*virtualYk)
 
        LBWF.AxesScreenY(i) = LBWF.ScrCenterY(1) - (SCM*LBWF.ZoomFac(1) * PY)
 
    next i
 
    'If the "visible" property of the axes is set to 1,
    'then draw the axes on the screen...
    
    if (LBWF.AxesVisible(1) = 1) then
 
        'Set the line thickness for the axes...
        print #main.wfscene, "size "; LBWF.AxesLineThickness(1)
 
        'Draw the x-axis (set color for x-axis first)
        print #main.wfscene, "color "; LBWF.XaxisColor$(1)
        x1 = LBWF.AxesScreenX(1) : y1 = LBWF.AxesScreenY(1)
        x2 = LBWF.AxesScreenX(2) : y2 = LBWF.AxesScreenY(2)
        print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
 
        'Draw the y-axis (set color for y-axis first)
        print #main.wfscene, "color "; LBWF.YaxisColor$(1)
        x1 = LBWF.AxesScreenX(1) : y1 = LBWF.AxesScreenY(1)
        x2 = LBWF.AxesScreenX(3) : y2 = LBWF.AxesScreenY(3)
        print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
 
        'Draw the z-axis (set color for z-axis first)
        print #main.wfscene, "color "; LBWF.ZaxisColor$(1)
        x1 = LBWF.AxesScreenX(1) : y1 = LBWF.AxesScreenY(1)
        x2 = LBWF.AxesScreenX(4) : y2 = LBWF.AxesScreenY(4)
        print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
 
        'Reset the line thickness back to 1...
        print #main.wfscene, "size 1"
 
    end if
 
    'Now that the screen coordinates of all of the nodes
    'have been determined, it is time to draw all of the
    'lines.  Draw the lines one object at a time, so
    'that line colors can be changed between objects...

    For obj = 1 to LBWF.ObjectCount(1)
 
    'Draw the object only if its "visible" property is set to 1...
    
    if (LBWF.ObjectVisible(obj) = 1) then
 
        'Set the drawing color for the object...
        DrawingColor$ = LBWF.ObjectColor$(obj)
        print #main.wfscene, "color "; DrawingColor$
 
        'Set the line thickness for the object...
        LineThickness = LBWF.ObjectLineThickness(obj)
        print #main.wfscene, "size "; LineThickness
 
        FirstLine = LBWF.ObjectFirstLine(obj)
        LastLine  = LBWF.ObjectLastLine(obj)
 
        for i = FirstLine to LastLine
            x1 = LBWF.NodeSX(LBWF.LineInode(i))
            y1 = LBWF.NodeSY(LBWF.LineInode(i))
            x2 = LBWF.NodeSX(LBWF.LineJnode(i))
            y2 = LBWF.NodeSY(LBWF.LineJnode(i))
 
            print #main.wfscene, "line "; x1; " "; y1; " "; x2; " "; y2
        next i
 
        'If needed, pause during testing of drawn objects...
        'PPP = FF.LBWF.PauseMilliseconds(1000)

    end if
 
 
    next obj
 
    'Reset the default line thickness back to 1...
    print #main.wfscene, "size 1" 
 
    'Set the default drawing color back to black...
    print #main.wfscene, "color black"
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestLibraryResources$()
 
    FF.LBWF.RequestLibraryResources$ = str$(LBWF.NodeResources(1)) + "  " + _
                                       str$(LBWF.LineResources(1)) + "  " + _
                                       str$(LBWF.ObjectResources(1))
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestRemainingResources$()
 
    RemainingNodes   = LBWF.NodeResources(1) - LBWF.NodeCount(1)
    RemainingLines   = LBWF.LineResources(1) - LBWF.LineCount(1)
    RemainingObjects = LBWF.ObjectResources(1) - LBWF.ObjectCount(1)
 
    FF.LBWF.RequestRemainingResources$ = str$(RemainingNodes) + "  " + _
                                         str$(RemainingLines) + "  " + _
                                         str$(RemainingObjects)
 
end Function
 
''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    'Determine the object on which to generate a report
    'by comparing the name argument against a list of object names...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenterX = LBWF.ObjectCenterX(ObjectOfReport)
    ObjectCenterY = LBWF.ObjectCenterY(ObjectOfReport)
    ObjectCenterZ = LBWF.ObjectCenterZ(ObjectOfReport)
 
    FF.LBWF.RequestObjectGeometricCenter$ = str$(ObjectCenterX) + "  " + _
                                            str$(ObjectCenterY) + "  " + _
                                            str$(ObjectCenterZ)
 
end Function
'''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.MoveObjectAbsolute(ObjectName$, pX, pY, pZ)
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    currentCenterX = val(word$(ObjectCenter$, 1))
    currentCenterY = val(word$(ObjectCenter$, 2))
    currentCenterZ = val(word$(ObjectCenter$, 3))
 
    transX = pX - currentCenterX
    transY = pY - currentCenterY
    transZ = pZ - currentCenterZ
 
    'Now, call the function which translates an object.
    'This will translate the object to the absolute
    'point identified by (pX,pY,pZ).
    
    AAA = FF.LBWF.TranslateObject(ObjectName$, transX, transY, transZ)
 
end Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectColor$(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectColor$ = LBWF.ObjectColor$(ObjectOfReport)
 
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectLineThickness(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectLineThickness = LBWF.ObjectLineThickness(ObjectOfReport)
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.HideAllObjects()
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        LBWF.ObjectVisible(i) = 0
    next i
 
 
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ShowAllObjects()
 
    OC = LBWF.ObjectCount(1)
 
    for i = 1 to OC
        LBWF.ObjectVisible(i) = 1
    next i
 
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.RequestObjectType$(ObjectName$)
 
    ObjectToIdentifyType = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToIdentifyType = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectType$ = LBWF.ObjectType$(ObjectToIdentifyType)
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.RotateObjectAboutY(ObjectName$, YRotationInDegrees)
 
    'Multiply the rotation angle by (-1)
    YRotationInDegrees = (-1) * YRotationInDegrees
 
    pi = 3.14159
    YRotRads = (YRotationInDegrees/360)*(2*pi)
 
    ObjectToRotate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToRotate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    CenterX = val(word$(ObjectCenter$,1))
    CenterY = val(word$(ObjectCenter$,2))
    CenterZ = val(word$(ObjectCenter$,3))
 
 
    ObjectsFirstNode = LBWF.ObjectFirstNode(ObjectToRotate)
    ObjectsLastNode  = LBWF.ObjectLastNode(ObjectToRotate)
 
    for i = ObjectsFirstNode to ObjectsLastNode
 
        deltaX = (LBWF.NodeWX(i) - CenterX)
        deltaZ = (LBWF.NodeWZ(i) - CenterZ)
        R      = sqr(deltaX^2 + deltaZ^2)
        OldAngleRads = FF.LBWF.ATAN2(deltaX, deltaZ)
 
        NewAngleRads = OldAngleRads + YRotRads
 
        LBWF.NodeWX(i) = CenterX + R*cos(NewAngleRads)
        LBWF.NodeWZ(i) = CenterZ + R*sin(NewAngleRads)
 
    next i
 
 
 
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function FF.LBWF.RotateObjectAboutX(ObjectName$, XRotationInDegrees)
 
    'Multiply the rotation angle by (-1)...
    XRotationInDegrees = (-1)*XRotationInDegrees
 
    pi = 3.14159
    XRotRads = (XRotationInDegrees/360)*(2*pi)
 
    ObjectToRotate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToRotate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    CenterX = val(word$(ObjectCenter$,1))
    CenterY = val(word$(ObjectCenter$,2))
    CenterZ = val(word$(ObjectCenter$,3))
 
    ObjectsFirstNode = LBWF.ObjectFirstNode(ObjectToRotate)
    ObjectsLastNode  = LBWF.ObjectLastNode(ObjectToRotate)
 
    for i = ObjectsFirstNode to ObjectsLastNode
 
        deltaY = (LBWF.NodeWY(i) - CenterY)
        deltaZ = (LBWF.NodeWZ(i) - CenterZ)
        R      = sqr(deltaY^2 + deltaZ^2)
        OldAngleRads = FF.LBWF.ATAN2(deltaZ, deltaY)
 
        NewAngleRads = OldAngleRads + XRotRads
 
        LBWF.NodeWZ(i) = CenterZ + R*cos(NewAngleRads)
        LBWF.NodeWY(i) = CenterY + R*sin(NewAngleRads)
 
    next i
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RotateObjectAboutZ(ObjectName$, ZRotationInDegrees)
 
    pi = 3.14159
    ZRotRads = (ZRotationInDegrees/360)*(2*pi)
 
    ObjectToRotate = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectToRotate = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    ObjectCenter$ = FF.LBWF.RequestObjectGeometricCenter$(ObjectName$)
 
    CenterX = val(word$(ObjectCenter$,1))
    CenterY = val(word$(ObjectCenter$,2))
    CenterZ = val(word$(ObjectCenter$,3))
 
    ObjectsFirstNode = LBWF.ObjectFirstNode(ObjectToRotate)
    ObjectsLastNode  = LBWF.ObjectLastNode(ObjectToRotate)
 
    for i = ObjectsFirstNode to ObjectsLastNode
 
        deltaY = (LBWF.NodeWY(i) - CenterY)
        deltaX = (LBWF.NodeWX(i) - CenterX)
        R      = sqr(deltaY^2 + deltaX^2)
        OldAngleRads = FF.LBWF.ATAN2(deltaX, deltaY)
 
        NewAngleRads = OldAngleRads + ZRotRads
 
        LBWF.NodeWX(i) = CenterX + R*cos(NewAngleRads)
        LBWF.NodeWY(i) = CenterY + R*sin(NewAngleRads)
 
    next i
 
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectVisibleState(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FF.LBWF.RequestObjectVisibleState = LBWF.ObjectVisible(ObjectOfReport)
 
End Function
 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.RequestObjectExtents$(ObjectName$)
 
    'Find the index number of the object by comparing
    'it against all the names in the list of objects...
    
    ObjectOfReport = 0
 
    for i = 1 to LBWF.ObjectCount(1)
        if (ObjectName$ = LBWF.ObjectName$(i)) then
            ObjectOfReport = i
            i = LBWF.ObjectCount(1)
        end if
    next i
 
    FirstNode = LBWF.ObjectFirstNode(ObjectOfReport)
    LastNode  = LBWF.ObjectLastNode(ObjectOfReport)
 
    Xmin = LBWF.NodeWX(FirstNode)
    Xmax = LBWF.NodeWX(FirstNode)
    Ymin = LBWF.NodeWY(FirstNode)
    Ymax = LBWF.NodeWY(FirstNode)
    Zmin = LBWF.NodeWZ(FirstNode)
    Zmax = LBWF.NodeWZ(FirstNode)
 
    for i = (FirstNode + 1) to LastNode
 
        if (LBWF.NodeWX(i) < Xmin) then
            Xmin = LBWF.NodeWX(i)
        end if
        if (LBWF.NodeWX(i) > Xmax) then
            Xmax = LBWF.NodeWX(i)
        end if
 
        if (LBWF.NodeWY(i) < Ymin) then
            Ymin = LBWF.NodeWY(i)
        end if
        if (LBWF.NodeWY(i) > Ymax) then
            Ymax = LBWF.NodeWY(i)
        end if
 
        if (LBWF.NodeWZ(i) < Zmin) then
            Zmin = LBWF.NodeWZ(i)
        end if
        if (LBWF.NodeWZ(i) > Zmax) then
            Zmax = LBWF.NodeWZ(i)
        end if
 
    next i
 
    FF.LBWF.RequestObjectExtents$ = str$(Xmin) + " " + str$(Xmax) + " " + _
            str$(Ymin) + " " + str$(Ymax) + " " + str$(Zmin) + " " + str$(Zmax)
 
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.ATAN2(x, y)
 
    pi = 3.14159265
    Result$ = "Undetermined"
    If (x = 0) and (y > 0) then
        FF.LBWF.ATAN2 = pi / 2
        Result$ = "Determined"
    end if
    if (x = 0) and (y < 0) then
        FF.LBWF.ATAN2 = 3 * pi / 2
        Result$ = "Determined"
    end if
    if (x > 0) and (y = 0) then
        FF.LBWF.ATAN2 = 0
        Result$ = "Determined"
    end if
    if (x < 0) and (y = 0) then
        FF.LBWF.ATAN2 = pi
        Result$ = "Determined"
    end if
    if (x = 0) and (y = 0) then
        FF.LBWF.ATAN2 = 0
        Result$ = "Determined"
    end if
 
    If Result$ = "Determined" then [End.of.function]
 
 
    BaseAngle = ATN(abs(y)/abs(x))
    If (x > 0) and (y > 0) then FF.LBWF.ATAN2 = BaseAngle
    If (x < 0) and (y > 0) then FF.LBWF.ATAN2 = pi - BaseAngle
    If (x < 0) and (y < 0) then FF.LBWF.ATAN2 = pi + BaseAngle
    If (x > 0) and (y < 0) then FF.LBWF.ATAN2 = 2*pi - BaseAngle
 
    [End.of.function]
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function FF.LBWF.FindPerpendicularDistance$(xa, ya, xb, yb, xc, yc)
 
    Distance.Is.Found = 0
 
    'Handle the case where the line between (xa,ya) and (xb,yb)
    'is a horizontal line...
    
    if (ya = yb) then
 
        primaryLineType$ = "horizontal"
        distance = abs(yc - ya)
        xd = xc
        yd = ya
        Distance.Is.Found = 1
 
    end if
 
    if (Distance.Is.Found = 1) then [Distance.Calc.Is.Complete] 
 
    'Handle the case where the line between (xa,ya) and (xb,yb)
    'is a vertical line...
    
    if (xa = xb) then
 
        primaryLineType$ = "vertical"
        distance = abs(xc - xa)
        xd = xa
        yd = yc
        Distance.Is.Found = 1
 
    end if
 
    if (Distance.Is.Found = 1) then [Distance.Calc.Is.Complete]
 
    'If program control has arrived at this location, then
    'the line between (xa, ya) and (xb, yb) is a diagonal
    'line.  Find the distance for this case...
    
    primaryLineType$ = "diagonal"
 
    'slope of the primary line...
    m1 = (ya - yb)/(xa - xb)
 
    'y-intercept of the primary line...
    b1 = ya - (m1 * xa)
 
    'slope of the perpendicular line...
    m2 = (-1)/m1
 
    'y-intercept of the perpendicular line...
    b2 = yc - (m2 * xc)
 
    'Calculate xd and yd, which are the coordinates
    'of the point where the perpendicular line intersects
    'the primary line...

    xd = (b2 - b1)/(m1 - m2)
    yd = (m2 * xd) + b2
 
    'Find the distance between (xc, yc) and (xd, yd)...
    distance = sqr((xc-xd)^2 + (yc-yd)^2)
 
    [Distance.Calc.Is.Complete]
 
    'Find out if the intersecting point in question
    'actually resides between (xa, ya) and (xb, yb)...
    
    xdydBetweenEndpoints$ = "no"
 
    if (primaryLineType$ = "vertical") then
 
        if ((yd >= min(ya,yb)) and (yd <= max(ya,yb))) then
            xdydBetweenEndpoints$ = "yes"
        end if
 
    end if 
 
    if (primaryLineType$ = "horizontal") then
 
        if ((xd >= min(xa,xb)) and (xd <= max(xa,xb))) then
            xdydBetweenEndpoints$ = "yes"
        end if 
 
    end if
 
    if (primaryLineType$ = "diagonal") then
 
        if ((xd >= min(xa,xb)) and (xd <= max(xa,xb))) then
            xdydBetweenEndpoints$ = "yes"
        end if
 
    end if
 
 
    FF.LBWF.FindPerpendicularDistance$ = str$(distance) + "  " + xdydBetweenEndpoints$
 
End Function
 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Top of Page

Return to Chapter 4: Wire 1.0 Released (Making Complex Objects With Wire).



Tom Nally
Steelweaver52@aol.com


Note: This linked source code accompanies Chapter 4: Wire 1.0 Released (Making Complex Objects With Wire), which originally appeared in the Liberty BASIC Newsletter, Issue #137. It is reprinted here with the permission of the author. - JanetTerra JanetTerra