Trigonometry - inverse...

Discussions related to mathematics, numerical methods, graph plotting etc.
Ivan
Posts: 127
Joined: Tue 07 May 2019, 16:47

Trigonometry - inverse...

Post by Ivan »

I'm a non-mathematical person, but now I have a very basic understanding of trigonometry and is discovering simple mathematics.

For a year ago I did not know the existence of a unit circle, vectors, but now e.g. radians gives some meaning.

Anyone who can explain the basics of inverse functions using BBCBASIC - please bear in mind, I'm new to this topic?
BBC Model B - 1984-1989. 6502 assembler, Unicomal 1988-1994, Some C and C++, Pascal 1990-1994. Bought a copy of BBC-BASIC 2007, but started to program at a daily basis 2019. C++ in 2021.
DDRM

Re: Trigonometry - inverse...

Post by DDRM »

Hi Ivan, not sure what you are looking for, and something like Wikipedia might be a good place to go, but, very simply:
Consider a right-angled triangle with a horizontal baseline and a point on the left. The line sloping up from the bottom left to top right is the hypotenuse, which is the longest side. I will call it C. The horizontal line I will call A, and the vertical line on the right I will call B.

There is an angle t (for theta) at the left "corner". Note that by default this is in radians, but you could put trigfunction(RAD(t)) if you want to use an angle in degrees, where trigfunction is any of the following...

The cosine of theta (COS(t) in BBC BASIC) is the ratio A/C
The sine (SIN(t) ) is the ratio B/C
The tangent (TAN(t) ) is the ratio B/A

The inverse functions take these ratios, and return the angle t (in radians). Again, there is a conversion function: DEG(trigfunction(Ratio)) will give the angle in degrees

arccosine (ACS(A/C) in BBC BASIC) will give the angle t for that ratio (i.e. that cosine value)
arcsine (ASN(B/C) ) gives t given a sin value
arctangent (ATN(B/A) gives the angle for a given tan value.

To give a concrete example, consider a triangle with hypotenuse of length 1 (unit circle!), and an angle t of 30 degrees on the left (=Pi/6 radians)
cos(t) ~ 0.866, sin(t) = 0.5, and tan(t) ~0.577 NB Cos and tan are approximate! Actually sqrt(3)/2 and 1/sqrt(3)
ACS(0.866) = ASN(t) = ATN(0.577) = PI/6, and DEG(ACS(0.866))=30

Things get a little harder to visualise when the angles are outside the range 0-90 degrees (0 - PI/2 radians), but just think of the hypotenuse moving as a radius around your unit circle. It may be helpful to think of the cosine as the projection of that line onto the x axis, and the sine as the projection onto the y axis (which they are). In the quadrant 90 - 180 degrees, the line projects up and left, so the cosine (and tangent) values become negative. In the range 180 - 270 degrees the line points down and left, so both cosine and sine are negative (but tan is positive, since the two negatives cancel out). In the last quadrant, 270-360 degrees (or, if you prefer, -90 - 0 degrees), the line points down and right, so cosine is positive, but sine (and tan) are negative.

Note that for the inverse functions, there is a problem: there are two places (for each function) where they can have a particular value. Cos and sin can have values in the range -1 to 1: ACS assumes this refers to the region 0 to 180 degrees, ASN and ATN assume -90 to + 90 degrees. It's then up to you to check the x and y values making up the ratio, and work out which quadrant it was ACTUALLY in....

Does that help?
Ivan
Posts: 127
Joined: Tue 07 May 2019, 16:47

Re: Trigonometry - inverse...

Post by Ivan »

Hi DDRM,

I'm afraid I have not been precisely enough:

I have to calculate theta, but I don't know how to use the tan function in BBCBASIC that way.

Thanks for your detailed reply.
You do not have the required permissions to view the files attached to this post.
BBC Model B - 1984-1989. 6502 assembler, Unicomal 1988-1994, Some C and C++, Pascal 1990-1994. Bought a copy of BBC-BASIC 2007, but started to program at a daily basis 2019. C++ in 2021.
DDRM

Re: Trigonometry - inverse...

Post by DDRM »

Hi Ivan,

Assuming you know y and x, then you can just use ATN:

theta = ATN(y/x)

This will give you the angle theta, in radians. If you do

theta = DEG(ATN(y/x)) you will get it in degrees.

You will note that you need to ensure x isn't 0, or you will get an error: you can check for this, and simply assign an angle of (+/-) 90 degrees/ PI/2 radians.

Note also, as discussed in the last post, if the angle is actually in the range 90 to 270 degrees, you'll need to correct for this (check whether x is negative, and add 180 degrees if it is).

Best wishes,
D
Ivan
Posts: 127
Joined: Tue 07 May 2019, 16:47

Re: Trigonometry - inverse...

Post by Ivan »

Hi DDRM,

Thanks a lot - you helped me a lot.

Did some exercies and have a basic understanding of trigonometry now.

Next subject will be vectors.

Best wishes,

Ivan

Code: Select all

      rem right triangle A, B, C
      rem unit circle
      mode 12

      x = 500
      y = 500

      Cx = 1500
      Cy = 600

      Ax = Cx - x
      Ay = Cy

      Bx = Cx
      By = Cy + y

      rem draw right triangle
      gcol 7
      move Ax, Ay
      draw Bx, By
      draw Cx, Cy
      draw Ax, Ay

      rem draw unit circle
      gcol 3
      move Cx, Cy
      for i = 0 to 2 * pi step pi / 180
        xp = cos(i) * x + Ax
        yp = sin(i) * y + Ay
        draw xp, yp
      next

      rem draw a vertical line
      gcol 5
      xp = cos(pi / 4) * x + Ax
      yp = sin(0) * y + Ay
      move xp, yp

      xp = cos(pi / 4) * x + Ax
      yp = sin(pi / 4) * y + Ay
      draw xp, yp
BBC Model B - 1984-1989. 6502 assembler, Unicomal 1988-1994, Some C and C++, Pascal 1990-1994. Bought a copy of BBC-BASIC 2007, but started to program at a daily basis 2019. C++ in 2021.
RichardRussell

Re: Trigonometry - inverse...

Post by RichardRussell »

DDRM wrote: Sun 29 Nov 2020, 21:57Assuming you know y and x, then you can just use ATN
Actually you can't: knowing both y and x means you can determine the angle completely, but ATN takes only one parameter so it gives an ambiguous result. The way to get the angle from y and x is to use the atan2 function, which takes two parameters. A BBC BASIC implementation can be found at the Wiki; I thought (hoped) this was extremely well known.
DDRM

Re: Trigonometry - inverse...

Post by DDRM »

Hi Richard,

Fair enough, though you CAN do it with ATN: you just need to check whether the answer is actually "on the right hand side" (i.e. x is positive) and correct. Of course the atan2 version is nice, since it does this for you. The built-in error trapping for x=0 is cool, too.
RichardRussell

Re: Trigonometry - inverse...

Post by RichardRussell »

DDRM wrote: Thu 03 Dec 2020, 15:09 though you CAN do it with ATN.
Your original phrase was "can just use ATN", which implies that you don't need to know any additional information, which you do.
you just need to check whether the answer is actually "on the right hand side" (i.e. x is positive) and correct.
You could equally have said "in the top half" (i.e. y is positive) because that also allows you to determine the quadrant. But in practice the code is simpler and faster if you use the signs of both x and y because that way you don't also need to store the result from ATN in a temporary, LOCAL, variable.

The following example programs, supplied with BBCSDL, all use the FNatan2 function; studying them may be instructive: Rubik.bbc, SkyBaby.bbc, aliens.bbc, bbcowl.bbc, skaters.bbc and world.bbc.
Ivan
Posts: 127
Joined: Tue 07 May 2019, 16:47

Re: Trigonometry - inverse...

Post by Ivan »

Ok - atn for angles between (left triangle) 0 and < 90 deg and atan2 for 360 deg...

Topic is also covered by javidx9 here: https://www.youtube.com/watch?v=DPfxjQ6sqrc

Thanks for clarification.

Code: Select all

      rem right triangle A, B, C
      rem unit circle
      rem test atn vs atan2
      mode 12

      x = 500
      y = 500

      Cx = 1500
      Cy = 600

      Ax = Cx - x
      Ay = Cy

      Bx = Cx
      By = Cy + y

      rem draw unit circle
      gcol 3
      for i = 0 to 2 * pi step pi / 4
        xp = cos(i) * x + Ax
        yp = sin(i) * y + Ay
        move Ax, Ay
        draw xp, yp
  
        r = fn_atan2(yp-Ay,xp-Ax)                  :rem gives correct quadrant
        rem r = atn((yp-Ay)/(xp-Ax))              :rem division by zero at 90 deg or pi / 2
  
        vdu 5
        print "rad: ";r;"  deg: ";deg(r)
        vdu4
  
      next

      end



      def fn_atan2(y,x) : on error local = sgn(y)*pi/2
      if x>0 then = atn(y/x) else if y>0 then = atn(y/x)+pi else = atn(y/x)-pi
BBC Model B - 1984-1989. 6502 assembler, Unicomal 1988-1994, Some C and C++, Pascal 1990-1994. Bought a copy of BBC-BASIC 2007, but started to program at a daily basis 2019. C++ in 2021.