Parabola, Hyperbola, Ellipse and Circle program for GLCD

MBB
2014-06-03
2014-06-03
  • MBB

    MBB - 2014-06-03

    This is an update to my previous post. I have added parabolas and filled ellipses/circles to my previous program. This version can plot all four conic sections on a GLCD.

    ;Chip Settings
    #chip 18F452,20
    #config OSC=HS
    
    ;Include files (Libraries)
    #include <GLCD.h>
    
    ;Defines (Constants)
        #define GLCD_DB0 PORTB.3     'D0 to pin 4 on LCD
        #define GLCD_DB1 PORTB.2     'D1 to pin 5 on LCD
        #define GLCD_DB2 PORTB.1     'D2 to pin 6 on LCD
        #define GLCD_DB3 PORTB.0     'D3 to pin 7 on LCD
        #define GLCD_DB4 PORTD.7     'D4 to pin 8 on LCD
        #define GLCD_DB5 PORTD.6     'D5 to pin 9 on LCD
        #define GLCD_DB6 PORTD.5     'D6 to pin 10 on LCD
        #define GLCD_DB7 PORTD.4     'D7 to pin 11 on LCD
        #define GLCD_CS2 PORTC.7     'D8 to pin 12 on LCD - CS1, CS2 are backwards
        #define GLCD_CS1 PORTC.6     'D9 to pin 13 on LCD - CS1, CS2 are backwards
        #define GLCD_RESET PORTC.5   'D10 to pin 14 of LCD
        #define GLCD_RW PORTC.4      'D11 to pin 15 of LCD
        #define GLCD_RS PORTD.3      'D12 to pin 16 D/I pin on LCD
        #define GLCD_ENABLE PORTD.2  'D13 to Pin 17 on LCD
    
    ;Variables
    Dim MajVTemp2, Maj_MinTemp As long; ellipse variables
    Dim MajV, MajV3, MinV, MinV3, Xvalue, Yvalue, OffsetX, OffsetY, MajVTemp, MajVTemp3 As integer; ellipse variables
    Dim MinV2, MajV2, Maj_Min, Min_Maj, Xaxis_Hor_ellipse, Xaxis_Hor_ellipse2 As long; ellipse variables
    Dim Yaxis_Hor_ellipse, Yaxis_Hor_ellipse2, Yaxis, Xaxis, y_1 As long; ellipse variables
    Dim TransAxis, ConjAxis, ValueX, ValueY, Xoffset, Yoffset As integer; hyperbola variables
    Dim AxisX, AxisY, AxisXX, AxisYY, AxisX_Hor_hyperbola, ValueX2, ValueY2 As integer; hyperbola variables
    Dim TransAxis2, Trans_Conj, AxisX_Hor_hyperbola2 As long; hyperbola variables
    Dim ConjAxis2, AxisY_Hor_hyperbola2, AxisY_Hor_hyperbola As long
    Dim Aterm, Bterm, Cterm, Xterm2, OffX, OffY, Xt, Yt As integer; parabola variables
    Dim Xterm, Yterm, Yterm2, XtermNew, YtermNew As integer; parabola variables
    Dim G_1 As long; square root variable
    
    'June 3, 2014
    'This program is used to plot Parabolas, Hyperbolas, Ellipses and Circles on an
    ' 128x64 GLCD. It can do both OPEN and FILLED ellipses/circles.  Due to the whole numbers
    '  used by GCB, the perimeters of the shapes are not completely smooth.  This is particualary
    '   noticeable with the parabola where the calculated value is derived from the square of
    '    the input number, i.e. a small change on the input produces a large change on the output.
    '     When plotting this, a small delta x (pset X) gives a large delta y (pset Y).  For this
    '      reason, in the parabola Sub the LINE sub was used in lieu of the PSET sub.
    '
    InitGLCD
    GLCDCLS
    
    '
    'Sample Vertical Parabolas - HVorientation = 0 for Vertical Parabola
    Parabola 1, 12, 5, 20, 30, 0; VERTICAL Parabola on left side of display
    Parabola 1, 12, 5, 50, 30, 0; VERTICAL Parabola in center of display
    Parabola -1, 12, 5, 100, 5, 0; Reversed VERTICAL Parabola on right side of display
    wait 3 s
    GLCDCLS
    
    'Sample HorizontalParabolas - HVorientation = 1 for Horizontal Parabola
    Parabola 1, 12, 5, 40, 35, 1; HORIZONTAL Parabola at center of display
    Parabola 9, 20, 20, 60, 7, 1; VERTICAL Parabola at top of display
    Parabola -5, 15, 10, 45, 50, 1; Reversed VERTICAL Parabola at bottom of display
    wait 3 s
    GLCDCLS
    
    'Sample Left-Right Hyperbola
    Hyperbola 15, 10, 63, 31, 3; Hyperbola in center of display
    wait 3 s
    GLCDCLS
    
    'Sample Top-Bottom Hyperbola
    Hyperbola 5, 5, 63, 31, 4; Hyperbola in center of display
    wait 3 s
    GLCDCLS
    
    ' Some sample OPEN HORIZONTAL ellipses - MajV > MinV,  HVtype = 0, Open_Fill = 0
    Ellipse 20, 12, 5, 5, 0, 0; Horizontal Ellipse on top left of display
    Ellipse 20, 12, 85, 5, 0, 0; Horizontal Ellipse on top right of display
    Ellipse 20, 12, 5, 34, 0, 0; Horizontal Ellipse on bottom left of display
    Ellipse 20, 12, 85, 34, 0, 0; Horizontal Ellipse on bottom right of display
    Ellipse 58, 20, 6, 12, 0, 0; Large centered Horizontal ellipse
    wait 3 s
    GLCDCLS
    
    ' Some sample FILLED HORIZONTAL ellipses - MajV > MinV,  HVtype = 0, Open_Fill = 1
    Ellipse 20, 12, 5, 5, 0, 1; Horizontal Ellipse on top left of display
    Ellipse 20, 12, 85, 5, 0, 1; Horizontal Ellipse on top right of display
    Ellipse 20, 12, 5, 34, 0, 1; Horizontal Ellipse on bottom left of display
    Ellipse 20, 12, 85, 34, 0, 1; Horizontal Ellipse on bottom right of display
    wait 3 s
    GLCDCLS
    
    ' Some sample OPEN VERTICAL ellipses - MajV > MinV,  HVtype = 1, Open_Fill = 0
    Ellipse 15, 10, 30, 0, 1, 0; Small Vertical Ellipse on top left of display
    Ellipse 15, 10, 80, 0, 1, 0; SmallVertical Ellipse on top right of display
    Ellipse 15, 10, 30, 32, 1, 0; Small Vertical Ellipse on bottom left of display
    Ellipse 15, 10, 80, 32, 1, 0; Small Vertical Ellipse on bottom right of display
    Ellipse 30, 10, 5, 0, 1, 0; Large Vertical ellipse on left side
    Ellipse 32, 10, 55, 0, 1, 0; Large Vertical ellipse in middle
    Ellipse 32, 10, 105, 0, 1, 0; Large Vertical ellipse on right side
    wait 3 s
    GLCDCLS
    
    ' Some sample FILLED VERTICAL ellipses - MajV > MinV,  HVtype = 1,  Open_Fill = 1
    Ellipse 15, 10, 30, 0, 1, 1; Small Vertical Ellipse on top left of display
    Ellipse 15, 10, 80, 0, 1, 1; SmallVertical Ellipse on top right of display
    Ellipse 15, 10, 30, 32, 1, 1; Small Vertical Ellipse on bottom left of display
    Ellipse 15, 10, 80, 32, 1, 1; Small Vertical Ellipse on bottom right of display
    Ellipse 30, 10, 5, 0, 1, 1; Large Vertical ellipse on left side
    Ellipse 32, 10, 55, 0, 1, 1; Large Vertical ellipse in middle
    Ellipse 32, 10, 105, 0, 1, 1; Large Vertical ellipse on right side
    wait 3 s
    GLCDCLS
    
    ' Some sample OPEN CIRCLES - MajV = MinV, HVtype = don't care, Circle Radius = MajV = MinV,  Open_Fill = 0
    Ellipse 15, 15, 10, 0, 0, 0; Circle on top left of display
    Ellipse 15, 15, 85, 0, 0, 0; Circle on top right of display
    Ellipse 15, 15, 10, 32, 0, 0; Circle on bottom left of display
    Ellipse 15, 15, 85, 32, 0, 0; Circle on bottom right of display
    Ellipse 20, 20, 43, 10, 0, 0; 0Circle in center of display
    wait 3 s
    GLCDCLS
    
    ' Some sample FILLED CIRCLES - MajV = MinV, HVtype = don't care, Circle Radius = MajV = MinV,  Open_Fill = 1
    Ellipse 15, 15, 10, 0, 0, 1; Circle on top left of display
    Ellipse 15, 15, 85, 0, 0, 1; Circle on top right of display
    Ellipse 15, 15, 10, 32, 0, 1; Circle on bottom left of display
    Ellipse 15, 15, 85, 32, 0, 1; Circle on bottom right of display
    Ellipse 20, 20, 43, 10, 0, 1; 0Circle in center of display
    wait 3 s
    GLCDCLS
    
    'SUB ROUTINES *****************************************
    '
    
    Sub Parabola (In Aterm, In Bterm, In Cterm, In OffX, In OffY, In HVorientation)
        'Uses the equation for a parabola -
        '  y = Ax^2 + Bx + C for vertical parabola or
        '  x = Ay^2 + By + C for horizontal parabola, where
        '   A is Aterm, Bis Bterm, and C is Cterm
        'A negative Aterm reverses direction of Parabola
        '
        Cnt1 = 0
        For Xt = -63 to 63
            On_Off = 1
    
            '
            Xterm2 = Xt * Xt
            Yterm = (Aterm * Xterm2) + (Bterm * Xt) + Cterm; VERTICAL Parabola Equation
    
            '
            If HVorientation = 1 then
                Xterm = Yterm + OffX; Reverse parameters for HORIZONTAL PARABOLA
                Yterm = Xt + OffY
            Else
                Yterm = Yterm + OffY; VERTICAL PARABOLA
                Xterm = Xt + OffX
            End If
    
            'Keep plot on GLCD screen
            If Xterm > 127 then
                Xterm = 127
            End If
    
            '
            If Xterm < 0 then
                Xterm = 0
            End If
    
            '
            If YTerm > 63 then
                Yterm = 63
            End If
    
            '
            If Yterm < 0 then
                Yterm = 0
            End If
    
            'Turn LINE off when parabola is off GLCD screen
            If (Xterm = 0) AND (XtermNew = 0) then
                On_Off = 0
            end if
    
            '
            If (Xterm = 127) AND (XtermNew = 127) then
                On_Off = 0
            end if
    
            '
            If (Yterm = 0) AND (YtermNew = 0) then
                On_Off = 0
            end if
    
            '
            If (Yterm = 63) AND (YtermNew = 63) then
                On_Off = 0
            end if
    
            'Allow loop through to establish XtermNew and YtermNew values that are on GLCD
            If Cnt1 = 1 then
                Line XtermNew, YtermNew, Xterm, Yterm, On_Off
            end if
            XtermNew = Xterm; Becomes previous Xterm value
            YtermNew = Yterm; Becomes previous Yterm value
            Cnt1 = 1
        Next Xt
    End Sub
    
    Sub Hyperbola (In TransAxis, In ConjAxis, In Xoffset, In Yoffset, In HypType)
        'Use the equation for an hyperbola -
        ' x^2/a^2 - y^2/b^2 = 1  which is rearranged to -
        '    x^2 = a^2/b^2 * (b^2 + y^2)
        ConjAxis2 = ConjAxis * ConjAxis; Conjugate Axis squared
        TransAxis2 = TransAxis * TransAxis ; TransAxis squared
        Trans_Conj = (100 * TransAxis2) / ConjAxis2; Scale up by 100
    
        '******************************************************
        If HypType = 3 then
            For ValueY = -32 to 32; ?????????????????????????
                ValueY2 = ValueY * ValueY
                On_Off1 = 1; To turn PSET on or off
                On_Off2 = 1
                AxisX_Hor_hyperbola2 = (Trans_Conj * (ConjAxis2 + ValueY2)) / 100; Scale down by 100
                Sq_Root AxisX_Hor_hyperbola2, AxisX_Hor_hyperbola
                AxisY = ValueY + Yoffset
                AxisX = Xoffset - AxisX_Hor_hyperbola
                AxisX_Hor_hyperbola = AxisX_Hor_hyperbola + Xoffset
                AxisYY = AxisY
    
                'Prevent negative values from plotting mirror image on display
                If (AxisX_Hor_hyperbola > 127) OR (AxisY > 63) OR (AxisX_Hor_hyperbola < 0) OR (AxisY < 0) then
                    AxisX_Hor_hyperbola = 0
                    AxisY = 0
                    On_Off2 = 0
                end if
    
                'Prevent negative values from plotting mirror image on display
                If (AxisX > 127) OR (AxisYY > 63) OR (AxisX < 0) OR (AxisYY < 0) then
                    AxisX = 0
                    AxisYY = 0
                    On_Off1 = 0
                end if
    
                '
                pset AxisX, AxisYY, On_Off1; Left half of hyperbola
                pset AxisX_Hor_hyperbola, AxisY, On_Off2; Right half of hyperbola
            Next ValueY
        End If
    
        '
        If HypType = 4 then
            For ValueX = -64 to 64
                ValueX2 = ValueX * ValueX
                On_Off1 = 1
                On_Off2 = 1
                AxisY_Hor_hyperbola2 = (Trans_Conj * (TransAxis2 + ValueX2 )) / 100; Scale down by 100
                Sq_Root AxisY_Hor_hyperbola2, AxisY_Hor_hyperbola
                AxisX = ValueX + Xoffset
                AxisY = AxisY_Hor_hyperbola + Yoffset;
                AxisY_Hor_hyperbola = Yoffset - AxisY_Hor_hyperbola;
                AxisXX = AxisX
    
                'Prevent negative values from plotting mirror image on display
                If (AxisY_Hor_hyperbola > 63) OR (AxisY > 63) OR (AxisY_Hor_hyperbola < 0) OR (AxisY < 0) then
                    AxisY_Hor_hyperbola = 0
                    AxisX = 0
                    On_Off2 = 0
                end if
    
                'Prevent negative values from plotting mirror image on display
                If (AxisXX > 127) OR (AxisY > 63) OR (AxisXX < 0) OR (AxisY < 0) then
                    AxisY = 0
                    AxisXX = 0
                    On_Off1 = 0
                end if
                pset AxisX, AxisY_Hor_hyperbola, On_Off2; Top half of hyperbola
                pset AxisXX, AxisY, On_Off1; Bottom half of hyperbola
            Next ValueX
        End If
    End Sub
    
    Sub Ellipse (In MajV, In MinV, In OffsetX, In OffsetY, In HVtype, In Open_Fill)
        'Use the equation for an ellipse -
        ' x^2/a^2 + y^2/b^2 = 1 for Horizontal ellipse.  This is rearranged to -
        '  x^2 = a^2/b^2 * (b^2 - y^2) OR y^2 = b^2/a^2 * (a^2 - x^2)
        '******************************************************
        'MajV is distance from center to a major vertex
        'MinV  is distance from center to a minor vertex
        'OffsetX is the distance from the y-axis to the left most edge of the ellipse
        'OffsetY is the distance from the x-axis to the top most edge of the ellipse
        'HVtype is 0 for HORIZONTAL or 1 for VERTICAL Ellipse and 0 or 1 for CIRCLE
        'CIRCLE is formed by setting MajV = Minv
        'Open_Fill is 0 for OPEN or 1 for FILLED Ellipse
        ' SYNTAX is  Ellipse  MajV, MinV, OffsetX, OffsetY, HVtype, Open_Fill
        '******************************************************
        If HVtype = 1 then
    
            'Swap values to use same equations for Horizontal and Vertical ellipses
            MajVTemp = MajV
            MajV = MinV
            MinV = MajVTemp
        End If
    
        '******************************************************
        'For a 128x64 GLCD -
        'HORIZONTAL ELLIPSE
        ' If 2*(Major Axis) plus OffsetX > 127, ellipse will move off RIGHT edge of screen
        ' If 2*(Minor Axis) plus OffsetY > 63, ellipse will move off BOTTOM edge of screen
        'VERTICAL ELLIPSE
        ' If 2*(Major Axis) plus OffsetY > 63, ellipse will move off BOTTOM edge of screen
        ' If 2*(Minor Axis) plus OffsetY > 127, ellipse will move off RIGHT edge of screen
        '
        '******************************************************
        If MinV > 31 then
            MinV = 31; keep ellipse on screen
        end if
    
        '
        If MajV > 63 then
            MajV = 63; keep ellipse on screen
        end if
    
        '******************************************************
        '
        MajVtemp = MajV
        MinVtemp = MinV
        OffsetXtemp = OffsetX
        OffsetYtemp = OffsetY
    
        '
        If Open_Fill = 0 then
            Goto SkipFill1
        end if
        If (HVtype = 1) AND (Open_Fill = 1) then
            Do While MinV > -1
            else
                Do While MajV > -1
                end if
                SkipFill1:
    
                '
                If ((2 * MajV) + OffsetX) > 127 then
                    OffsetX = 127 - (2 * MajV)
                end If
    
                '
                If ((2 * MinV) + OffsetY) > 63 then
                    OffsetY = 63 - (2 * MinV)
                end If
    
                '
                If MajV < 0 then
                    MajV = 0; Prevent overflow
                end if
                MinV3 = MinV * (-1); Negative of MinV
                MinV2 = MinV * MinV; MinV squared
                MajV2 = MajV * MajV; MajV squared
    
                '
                If MinV = 0 then
                    MinV2 = 1; Prevent Divide by zero
                End If
                Maj_Min = (100 * MajV2) / MinV2; Scale up by 100
    
                '******************************************************
                For Yvalue = MinV3 to MinV
    
                    '
                    Xaxis_Hor_ellipse2 = (Maj_Min * (MinV2 - (Yvalue * Yvalue))) / 100; Scale down by 100 and Solve for X
                    Sq_Root Xaxis_Hor_ellipse2, Xaxis_Hor_ellipse
    
                    '
                    Yaxis = Yvalue + MinV + OffsetY
                    Xaxis = abs(Xaxis_Hor_ellipse - MajV) + OffsetX
                    Xaxis_Hor_ellipse = Xaxis_Hor_ellipse + MajV + OffsetX
    
                    '
                    If Open_Fill = 0 then
                        pset Xaxis, Yaxis, on; Left half of ellipse
                        pset Xaxis_Hor_ellipse, Yaxis, on; Right half of ellipse
                    End If
                    If Open_fill = 1 then
                        Line Xaxis, Yaxis, Xaxis_Hor_ellipse, Yaxis
                    End If
    
                    '
                Next Yvalue
                MinV = MinV - 1
                MajV = MajV - 1
                OffsetX = OffsetX + 1
                OffsetY = OffsetY + 1
                If (OffsetX > OffsetXtemp + 2 * MajV) AND (HVtype = 1) then
                    OffsetX = OffsetX - 1; prevent Vertical Ellipse from Extending in X-axis direction
                End If
                If Open_Fill = 1 then
                Loop
            end if
    
            '******************************************************
            ' Fill in openings
            FillOpenings:
            If Open_Fill = 1 then
                Goto SkipFO
            end if
            MajV = MajVtemp
            MinV = MinVtemp
            OffsetX = OffsetXtemp
            OffsetY = OffsetYtemp
    
            '
            If Open_Fill = 0 then
                Goto SkipFill2
            end if
            If HVtype = 1 AND (Open_Fill = 1) then
                Do While MinV > -1
                else
                    Do While MajV > -1
                    end if
                    SkipFill2:
    
                    '
                    If ((2 * MajV) + OffsetX) > 127 then
                        OffsetX = 127 - (2 * MajV)
                    end If
    
                    '
                    If ((2 * MinV) + OffsetY) > 63 then
                        OffsetY = 63 - (2 * MinV)
                    end If
    
                    '
                    If MinV < 0 then
                        MinV = 0; Prevent overflow
                    end if
                    MajV3 = MajV * (-1); Negative of MajV
                    MinV2 = MinV * MinV; MinV squared
                    MajV2 = MajV * MajV; MajV squared
    
                    '
                    If MajV = 0 then
                        MajV2 = 1; Prevent Divide by zero
                    end if
                    Min_Maj = (100 * MinV2) / MajV2; Scale up by 100
    
                    '
                    For Xvalue = MajV3 to MajV
                        Yaxis_Hor_ellipse2 = (Min_Maj * (MajV2 - (Xvalue * Xvalue))) / 100; Scale down by 100 and Solve for Y
                        Sq_Root Yaxis_Hor_ellipse2, Yaxis_Hor_ellipse
    
                        '
                        Xaxis = Xvalue + MajV + OffsetX
                        Yaxis = Yaxis_Hor_ellipse + MinV + OffsetY; Top half of ellipse
                        Yaxis_Hor_ellipse = abs(Yaxis_Hor_ellipse - MinV) + OffsetY;
    
                        '
                        If Open_Fill = 0 then
                            pset Xaxis, Yaxis_Hor_ellipse, on; Top half of ellipse
                            pset Xaxis, Yaxis, on; Bottom half of ellipse
                        End If
                        If Open_Fill = 1 then
                            line Xaxis, Yaxis_Hor_ellipse, Xaxis, Yaxis
                        End If
    
                        '
                    Next Xvalue
    
                    '
                    MinV = MinV - 1
                    MajV = MajV - 1
                    OffsetX = OffsetX + 1
                    OffsetY = OffsetY + 1
                    If (OffsetY > OffsetYtemp + 2 * MinV) AND (HVtype = 0) then
                        OffsetY = OffsetY - 1; prevent Horizontal Ellipse from Extending in Y-axis direction
                    End If
                    If Open_Fill = 1 then
                    Loop
                end if
                SkipFO:
    End Sub
    
    Sub Sq_Root (In y_1, G_1)
        'SQUARE ROOT Approximation
        G_1 = 600; First Guess for 6 Digit y_1
        If y_1 < 100000 then
            G_1 = 200; First Guess for 5 Digit y_1
        End If
        If y_1 < 10000 then
            G_1 = 60; First Guess for 4 Digit y_1
        End If
        If y_1 < 1000 then
            G_1 = 20; First Guess for 3 Digit y_1
        End If
        If y_1 < 100 then
            G_1 = 6; First Guess for 2 Digit y_1
        End If
        If y_1 < 10 then
            G_1 = 2; First Guess for 1 Digit y_1
        End If
    
        '
        G_1 = (G_1 + (y_1 / G_1))/2
        G_1 = (G_1 + (y_1 / G_1))/2
        G_1 = (G_1 + (y_1 / G_1))/2
        G_1 = (G_1 + (y_1 / G_1))/2
        G_1 = (G_1 + (y_1 / G_1))/2; Square Root of y_1
    End Sub
    
     
  • Anonymous - 2014-06-03

    MBB, that's fantastic work! Thanks for sharing it.

     

Log in to post a comment.