Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Getting vectors using a lookup table
#1
More playing around today. I created a few functions to quickly get vector quantities from a SIN lookup table.

The SIN/COSINE table returns standard results while the conversion functions negate the COSINE value so 0 degrees and 0Pi are north/up.

Code: (Select All)
'+-------------------------------------------------------+
'|   Radian to Vector and Degree to Vector subroutines   |
'|                          by                           |
'|                    Terry Ritchie                      |
'|                       05/14/24                        |
'|                                                       |
'| Convert radians or degrees to vector pairs using a    |
'| pre-calculated lookup table or real-time calculation. |
'| Documentation contained in subs.                      |
'|                                                       |
'| R2VX!(radian, mode) - return radian x vector          |
'| R2VY!(radian, mode) - return radian y vector          |
'| D2VX!(degree, mode) - return degree x vector          |
'| D2VY!(degree, mode) - return degree y vector          |
'| SINE!(Index)        - return SINE   from lookup table |
'| COSINE!(Index)      - return COSINE from lookup table |
'|                                                       |
'| R2VX!, R2VY!, D2VX!, and D2VY! return vector values   |
'| based on the following input values:                  |
'|                                                       |
'|   0 = North    90 = East  180 = South    270 = West   |
'| 0Pi = North  .5Pi = East   Pi = South  1.5Pi = West   |
'|                                                       |
'| Degrees based on 0 to 359, radians from 0 to 2Pi.     |
'+-------------------------------------------------------+

'+--------------------+
'| Begin demo program |
'+--------------------+

CONST MODE% = 0 ' (0 to use lookup table, 1 to calculate in real time)

DIM d AS SINGLE ' counter

SCREEN _NEWIMAGE(640, 480, 32)

' Draw line from center point using degree values passed in

FOR d = 0 TO 359
    LINE (319, 239)-(319 + D2XV(d, MODE) * 200, 239 + D2YV(d, MODE) * 200)
    _DELAY .005
NEXT d
SLEEP
CLS

' Draw line from center point using radian values passed in

FOR d = 0 TO 2 * _PI STEP 2 * _PI / 360
    LINE (319, 239)-(319 + R2XV(d, MODE) * 200, 239 + R2YV(d, MODE) * 200)
    _DELAY .005
NEXT d

'+------------------+
'| End demo program |
'+------------------+

'------------------------------------------------------------------------------------------------------------
FUNCTION R2XV! (rad AS SINGLE, mode AS INTEGER) ' radian to x vector

    '+---------------------------------------------------------------------------+
    '| Converts a radian value passed in to the corresponding x vector value.    |
    '| 0Pi = North/Up, .5Pi = East/Right, Pi = South/Down, 1.5Pi = West/Left.    |
    '|                                                                           |
    '| rad  - the radian value to convert to x vector                            |
    '| mode - 0 return value from lookup table, not 0 return calculated value    |
    '|                                                                           |
    '| Note: To use the lookup table the radian value needs to be converted to a |
    '|       degree value. The lookup table only contains the values for integer |
    '|       degrees ranging from 0 to 359. If you need a more precise           |
    '|       calculation set mode above to a non xero integer value.             |
    '+---------------------------------------------------------------------------+

    IF mode THEN '                 calculate vector?
        R2XV! = SIN(rad) '         yes, return calculated SINE value
    ELSE '                         no, use lookup table
        R2XV! = SINE!(_R2D(rad)) ' return SINE value from table
    END IF

END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION R2YV! (rad AS SINGLE, mode AS INTEGER) ' radian to y vector

    '+---------------------------------------------------------------------------+
    '| Converts a radian value passed in to the corresponding y vector value.    |
    '| 0Pi = North/Up, .5Pi = East/Right, Pi = South/Down, 1.5Pi = West/Left.    |
    '|                                                                           |
    '| rad  - the radian value to convert to y vector                            |
    '| mode - 0 return value from lookup table, not 0 return calculated value    |
    '|                                                                           |
    '| Note: To use the lookup table the radian value needs to be converted to a |
    '|       degree value. The lookup table only contains the values for integer |
    '|       degrees ranging from 0 to 359. If you need a more precise           |
    '|       calculation set mode above to a non xero integer value.             |
    '+---------------------------------------------------------------------------+

    IF mode THEN '                    calculate vector?
        R2YV! = -COS(rad) '           yes, return calculated COSINE value (negate so 0 = north)
    ELSE '                            no, use lookup table
        R2YV! = -COSINE!(_R2D(rad)) ' return COSINE value from table (negate so 0 = north)
    END IF

END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION D2XV! (deg AS SINGLE, mode AS INTEGER) ' degree to x vector

    '+---------------------------------------------------------------------------+
    '| Converts a degree value passed in to the corresponding x vector value.    |
    '| 0 = North / Up, 90 = East / Right, 180 = South / Down, 270 = West / Left. |
    '|                                                                           |
    '| deg  - the degree value to convert to x vector                            |
    '| mode - 0 return value from lookup table, not 0 return calculated value    |
    '|                                                                           |
    '| Note: The lookup table only contains SIN/COS values for integer degrees   |
    '|       ranging from 0 to 359. If you need a more precise calculation set   |
    '|       mode above to a non zero integer value.                             |
    '+---------------------------------------------------------------------------+

    IF mode THEN '               calculate vector?
        D2XV! = SIN(_D2R(deg)) ' yes, return calculated SINE value
    ELSE '                       no, use lookup table
        D2XV! = SINE!(deg) '     return SINE value from table
    END IF

END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION D2YV! (deg AS SINGLE, mode AS INTEGER) ' degree to y vector

    '+---------------------------------------------------------------------------+
    '| Converts a degree value passed in to the corresponding y vector value.    |
    '| 0 = North / Up, 90 = East / Right, 180 = South / Down, 270 = West / Left. |
    '|                                                                           |
    '| deg  - the degree value to convert to y vector                            |
    '| mode - 0 return value from lookup table, not 0 return calculated value    |
    '|                                                                           |
    '| Note: The lookup table only contains SIN/COS values for integer degrees   |
    '|       ranging from 0 to 359. If you need a more precise calculation set   |
    '|       mode above to a non zero integer value.                             |
    '+---------------------------------------------------------------------------+

    IF mode THEN '                 calculate vector?
        D2YV! = -COS(_D2R(deg)) '  yes, return calculated COSINE value (negate so 0 = north)
    ELSE '                         no, use lookup table
        D2YV! = -COSINE!(deg) '    return COSINE value from table (negate so 0 = north)
    END IF

END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION SINE! (Index AS INTEGER) ' SINE lookup table

    '+--------------------------------------------------+
    '| Returns a SINE value from the SINE lookup table. |
    '|                                                  |
    '| Index - 0 to 359                                 |
    '+--------------------------------------------------+

    STATIC x(360) AS SINGLE ' SINE lookup table persistent values
    DIM d AS INTEGER '        data counter

    '+-----------------------------------------------------------------+
    '| Build the SINE lookup table the first time subroutine is called |
    '+-----------------------------------------------------------------+

    IF x(90) = 0 THEN '          has the lookup table been built?
        DO '                     no, begin data read loop
            READ x(d) '          SINE   0 through  90
            x(180 - d) = x(d) '  SINE  90 through 180
            x(180 + d) = -x(d) ' SINE 180 through 270
            x(360 - d) = -x(d) ' SINE 270 through 360
            d = d + 1 '          increment degree counter
        LOOP UNTIL d = 91 '      leave when all data values read
    END IF
    SINE! = x(Index) '           return SINE

    '+------------------------------------------------------------------------------------------------------+
    '| The values for SINE 0 to 0.5PI (0 to 90 degrees)                                                     |
    '|                                                                                                      |
    '| I know what you're thinking, "Why not just calculate these and then place the values into the array  |
    '| table?" I was getting strange anomolies in the returned values. For instance, sometimes .49999999 or |
    '| .50000001 would show up for .5 and other times numbers like this would appear .58778552520000001.    |
    '| Creating and using this data set ensures consistent values.                                          |
    '+------------------------------------------------------------------------------------------------------+

    DATA 0
    DATA .017452406,.034899496,.052335956,.069756473,.087155742,.104528463,.121869343,.139173100,.156434465
    DATA .173648177,.190808995,.207911690,.224951054,.241921895,.258819045,.275637355,.292371704,.309016994
    DATA .325568154,.342020143,.358367949,.374606593,.390731128,.406736643,.422618261,.438371146,.453990499
    DATA .469471562,.484809620,.500000000,.515038074,.529919264,.544639035,.559192903,.573576436,.587785252
    DATA .601815023,.615661475,.629320391,.642787609,.656059028,.669130606,.681998360,.694658370,.707106781
    DATA .719339800,.731353701,.743144825,.754709580,.766044443,.777145961,.788010753,.798635510,.809016994
    DATA .819152044,.829037572,.838670567,.848048096,.857167300,.866025403,.874619707,.882947592,.891006524
    DATA .898794046,.906307787,.913545457,.920504853,.927183854,.933580426,.939692620,.945518575,.951056516
    DATA .956304755,.961261695,.965925826,.970295726,.974370064,.978147600,.981627183,.984807753,.987688340
    DATA .990268068,.992546151,.994521895,.996194698,.997564050,.998629534,.999390827,.999847695,1.00000000

END FUNCTION
'------------------------------------------------------------------------------------------------------------
FUNCTION COSINE! (Index AS INTEGER) ' COSINE lookup table

    '+---------------------------------------------------+
    '| Returns a COSINE value from the SIN lookup table. |
    '|                                                   |
    '| Index - 0 to 359                                  |
    '+---------------------------------------------------+

    SELECT CASE Index '                     which array index to return?
        CASE 0 TO 89 '                      quadrant 1
            COSINE! = SINE!(90 - Index) '   return equivalent from SINE table
        CASE 90 TO 179 '                    quadrant 2
            COSINE! = -SINE!(Index - 90) '  return equivalent from SINE table
        CASE 180 TO 269 '                   quadrant 3
            COSINE! = -SINE!(270 - Index) ' return equivalent from SINE table
        CASE 270 TO 359 '                   quadrant 4
            COSINE! = SINE!(Index - 270) '  return equivalent from SINE table
    END SELECT

END FUNCTION
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#2
-----
Reply
#3
-----
Reply




Users browsing this thread: 2 Guest(s)