Menu

Error in Atan function ?

Help
MBB
2022-06-14
2022-06-20
  • MBB

    MBB - 2022-06-14

    I'm using GCBASIC 0.99.01 2022-01-27 (Windows 64 bit) : Build 1073 with the 18F4550 chip.

    I'm trying to use this : byte_variable = atan (x_vector,y_vector) which is in #include <maths.h></maths.h>

    First a question:
    There are at least 2 coordinate systems. The Cartesian Coordinates where 0 degrees is the +X axis, 90 degrees is the +Y axis, 180 is -X axis and 270 is -Y axis. (Counter clockwise rotation from 0 degrees)

    The other is the Compass coordinate system where 0 degrees is the +Y axis, 90 degrees is the +X axis, 180 is the -Y axis and 270 is the -X axis. (Clockwise rotation from 0 degrees)

    The Help file doesn't mention it but It appears that this function uses the Compass coordinate system. Is that correct?

    Now the error in the function.
    If X is negative and Y is positive, GCB gives the wrong answer.

    For example: If X = -25 and Y = 45, Degrees = Atan (Y/X) = Atan (-25/45) = -29 degrees.

    With -X, +Y, the Compass coordinate system would give 119 degrees.
    The Compass coordinate system would give 330 degrees.

    But GCB gives 75 degrees.

     
  • William Roth

    William Roth - 2022-06-15

    ATan returns a WORD value, not a byte as in the main description. A few lines down it says it returns a WORD. So confusing a bit.

    When I use a BYTE I get 75.
    When I use a WORD I get 331.

    #chip 18F25K22, 16
    #config Osc = IntIO67
    
    #include <maths.h>
    
    #define USART_BAUD_RATE 9600
    #define USART_TX_BLOCKING
    
    Dim Word_Result as WORD
    Dim Byte_Result as BYTE
    
    Do
        Byte_Result = ATan(-25,45)
        Word_Result = ATan(-25,45)
        Hserprint "Byte Result = " : Hserprint Byte_Result : HserprintCRLF
        Hserprint "Word Result = " : Hserprint Word_Result : HserprintCRLF 2
    
        Wait 1 s
    
    Loop
    
     

    Last edit: William Roth 2022-06-15
  • MBB

    MBB - 2022-06-15

    Thanks William that solved it.

    Anobium,

    The Help file doesn't mention it but It appears that this function uses the Compass coordinate system. Is that correct?

    I would suggest the Help file specify if this function outputs degrees based on the Cartesian Coordinate system or the Compass coordinate system.

    To me, it looks like the Compass coordinate system.

     
  • stan cartwright

    stan cartwright - 2022-06-15

    @William Roth "ATan returns a WORD value, not a byte as in the main description. A few lines down it says it returns a WORD. So confusing a bit."

    true
    Byte_Result = ATan(-25,45)
    Word_Result = ATan(-25,45)
    negative numbers not as expected.
    Suppose I don't understand signed integers :)

    I've never used ATan so looking it up. I've tried the sin cos using Trig.h which is useful for glcd dials... or maybe missile command or 2 us rangefinders for robots.
    I'll see what ATan can be useful for.

    'This version takes any +/- XY vector and returns degrees 0-360
    'v1.01
    Function ATan ( xvector as integer, yvector as integer ) as word
    'Fast XY vector to integer degree algorithm - Jan 2011 www.RomanBlack.com
    'See http://www.romanblack.com/integer_degree.htm
    'Converts any XY values including 0 to a degree value that should be
    'within +/- 1 degree of the accurate value without needing
    'large slow trig functions like ArcTan() or ArcCos().
    'NOTE! at least one of the X or Y values must be non-zero!
    'This is the full version, for all 4 quadrants and will generate
    'the angle in integer degrees from 0-360.
    'Any values of X and Y are usable including negative values provided
    'they are between -1456 and 1456 so the 16bit multiply does not overflow.
    ;

     
  • William Roth

    William Roth - 2022-06-16

    It appears that the Help is also confusing/misleading for Sine, Cosine & Tangent.

    From the Help:

    Trigonometry Sine, Cosine and Tangent

    Syntax:

    byte_variable = sin( word_variable )

    byte_variable = cos( word_variable )

    byte_variable = tan( word_variable )

    Explanation:

    Great Cow BASIC supports Three Primary Trigonometric Functions

    Great Cow BASIC supports the following functions, sin(x), cos(x), tan(x), where x is a
    signed integer
    representing an angle measured in a whole number of degrees. The
    output values are also integers
    , represented as fixed point decimal fractions.


    The "syntax" seems to be incorrect. Both "byte_variable" and "word_variable" should instead be integer variables.

    Someone please correct me if I am wrong (before I edit the Help)

    William

     
    • Anobium

      Anobium - 2022-06-16

      If the methods in the library are Word ( in ) and returns an Integer then you are correct and the Help is incorrect.

       
    • Anobium

      Anobium - 2022-06-16

      If the methods in the library are Word ( in ) and returns an Integer then you are correct and the Help is incorrect.

       
  • William Roth

    William Roth - 2022-06-16

    From the Library(s)

    • function sin(in trig_arg2 as integer) as integer
    • function cos(in trig_arg2 as integer) as integer
    • function tan(in trig_arg2 as integer) as integer

    So looks like integer in and returns integer in all cases

     
    • Anobium

      Anobium - 2022-06-16

      Looks correct from your analysis.

       
  • stan cartwright

    stan cartwright - 2022-06-17

    I had to learn trig as part of passing maths in school but never used it in any jobs.
    I've used trig 2 places. h ok. works like a compass /clock and sin, cos work fast on a glcd.
    A circle using trig looks different to the circle command.

    Google ATan gives little relevant to gcb ... stuff with pi. Whatever it does it's probably fast as it's a math function but it's not easy to find a use for it explained.

    I tried a glcd clock but it's the hand sub that does it all and so simple
    https://www.youtube.com/watch?v=Uxxo2zDLM-o

    #chip mega328p, 16
    #option explicit
    #include <glcd.h>
    #INCLUDE <TRIG2PLACES.H>
    ;
    #define GLCD_TYPE GLCD_TYPE_ILI9341
    #define GLCD_DC   portb.2
    #define GLCD_CS   portd.7
    #define GLCD_RESET   portd.4 ; Reset line Tie high..not needed
    #define GLCD_DO   portb.3 ;  MOSI SDI
    #define GLCD_SCK   portb.5 ;    SCK
    #define ILI9341_HardwareSPI    ' remove/comment out if you want to use software SPI.
    #define GLCD_EXTENDEDFONTSET1
    GLCDfntDefaultsize = 2
    GLCDRotate (portrait)
    GLCDCLS ILI9341_BLACK
    ;
    dim radius,xcentre,ycentre,xend,yend as byte
    dim angle,seconds,minutes,oldseconds,oldminutes,minstmp,hours,oldhours,handcolour as word
    ;draw dial
    Circle (160,120,90,ILI9341_green)
    for angle= 0 to 359 step 6
      xend = 160 + 210  * sin (angle)/255
      yend = 120 - 210  * cos (angle)/255
      pset (xend,yend,ILI9341_yellow) ;second marks
    next angle
    ;
    for angle= 0 to 359 step 30
      xend = 160 + 218  * sin (angle)/255
      yend = 120 - 218  * cos (angle)/255
      pset (xend,yend,ILI9341_white) ;5 minute marks
    next angle
    ;
    radius=200
    xcentre=160
    ycentre=120
    hours=11*30 ;  set clock  to Hours 11:Minutes 58:Seconds 50
    minutes=58*6 ; hours*30:minutes*6:seconds*6
    seconds=50*6
    hours=hours+(minutes/72)*6 ; nudge hour hand to minute division
    ;
    ;start main
    do
      oldseconds=seconds
      seconds=seconds+6
      if seconds=360 then
        seconds=0
        oldminutes=minutes
        minutes=minutes+6
        minstmp=minstmp+6
        if minutes=360 then
          minutes=0
        end if
        if minstmp>=72 Then ;1/5th circle
          minstmp=0
          oldhours=hours
          hours=hours+6 ;increase hour hand by 1 minute division every 12 minutes
          if hours=360 Then
            hours=0
          end if
        end if
      end if
    ;erase old hands
      angle=oldseconds
      handcolour=ILI9341_black
      radius=200
      hand
    ;
      angle=oldminutes
      handcolour=ILI9341_black
      radius=180
      hand
    ;
      angle=oldhours
      handcolour=ILI9341_black
      radius=150
      hand
    ;draw updated hands
      angle=seconds
      handcolour=ILI9341_GREEN
      radius=200
      hand
    ;
      angle=minutes
      handcolour=ILI9341_SILVER
      radius=180
      hand
    ;
      angle=hours
      handcolour=ILI9341_FUCHSIA
      radius=150
      hand
    ;  wait 998 ms ;adjust for time keeping accuracy
    loop
    ;
    sub hand
      xend = xcentre + radius  * sin (angle)/255
      yend = ycentre - radius  * cos (angle)/255
      line (xcentre,ycentre,xend,yend,handcolour)
    end sub
    
     

    Last edit: stan cartwright 2022-06-17
  • Anobium

    Anobium - 2022-06-20

    I have updated the Help to correct to integer variables.

    I have updated and corrected the following :

    1. trigonometry.adoc
    2. trigonometryatan.adoc
    3. trigonometrycircles.adoc

    See https://github.com/GreatCowBASIC/Help/tree/main/source for the latest source files. The next update (GCStudio) will contain these updates.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.