Inverse Sin and Cosine

Date:    Thu, 31 Oct 1996 13:09:29 +0000
From:    Andrew White <andy.white@dial.pipex.com>
Subject: Re: finding an angle
Angle measurement is valid for a ratio of 1 or 0 if you're measuring angles between two vectors. Also you might be using the Cosine rule for a general triangle rather than just right angled triangles ;) So for completeness:-
on asin ratio
  if ratio < 1 and ratio > -1 then
    return atan(ratio/sqrt(1.0 - (ratio * ratio)))
  else if ratio = 1 then
    return pi()/2
  else if ratio = -1 then
    return -pi()/2
  end if
end

on acos ratio
  if ratio < 0 then
    return pi() + atan(sqrt(1.0 - (ratio * ratio))/ratio)
  else if ratio > 0 then
    return atan(sqrt(1.0 - (ratio * ratio))/ratio)
  else
    return pi()/2
  end if
end

on radToDeg radAngle
  return radAngle*180.0/pi()
end

on degToRad degAngle
  return degAngle*pi()/180.0
end

Date:    Tue, 29 Oct 1996 09:22:14 -0000
From:    Andrew White <andy.white@dial.pipex.com>
Subject: Re: finding an angle
It uses the dot product of two vectors to get the cosine of the angle between the two vectors. It always returns the smallest angle between the two vectors and is always positive. I think it checks for all the possible div by zero errors but I could be wrong.

A little trig is required to get the tangent of the angle between the two vectors so that we can use the atan() function.

IMHO it's about time we had acos() and asin() in lingo.

--------- handler code --------------

on findAngle ax,ay,bx,by,cx,cy

  -- build the vectors by subtracting the common point

  set x1 = ax - bx
  set x2 = cx - bx
  set y1 = ay - by
  set y2 = cy - by

  -- calculate the magnitude of the vectors using Pythagoras

  set m1 = sqrt(float((x1 * x1) + (y1 * y1)))
  set m2 = sqrt(float((x2 * x2) + (y2 * y2)))

  -- check for zero vectors and if ok then calculate the
  -- dot product otherwise return zero as the angle

  if m1 * m2 <> 0 then

    set costheta = ((x1 * x2) + (y1 * y2))/(m1 * m2)

  else

    set theta = 0
    return theta

  end if

  -- as there's no arccos in lingo we have to do a quick
  -- bit of trig to get tan theta so we can use atan()

  set sintheta = sqrt(1 - (costheta * costheta))

  -- check for zero cos theta - if ok calculate tan theta

  if costheta > 0 then

    set tantheta = sintheta/costheta
    set theta = atan(tantheta)

    -- if cos theta negative subtract the absolute value of
    -- atan so we always get the smallest angle
    -- atan() returns radians so we use the pi() function to
    -- represent 180 degrees

  else if costheta < 0 then

    set tantheta = sintheta/costheta
    set theta = pi() - abs(atan(tantheta))

  else

    -- if cos theta is zero then theta is 90 degrees

    set theta = pi()/2

  end if

  -- convert theta to degrees from radians and return value

  return integer(theta * 180 / pi())

end

--------- end handler code -----------

Date:    Tue, 29 Oct 1996 09:37:59 -0500
From:    "Glenn M. Picher" <gpicher@maine.com>
Subject: Re: finding an angle

>IMHO it's about time we had acos() and asin() in lingo.
OK.
  on asin ratio
    return atan(ratio/sqrt(1.0 - (ratio * ratio)))
  end
If ratio is less than or equal to -1.0, or greater than or equial to 1.0, then you get a divide by zero error. But that wouldn't be a valid triangle anyway, so an angle measurement would be meaningless.
  on acos ratio
    return atan(sqrt(1.0 - (ratio * ratio))/ratio)
  end
If ratio is 0.0, you get a divide by zero error. But that wouldn't be a valid triangle, either.

If I understand correctly, atan() is the only trig function that math coprocessor chips and math libraries support intrinsically; the other transcendental functions are all derived through transformations just like those above. Of course, having asin() and acos() built in to Lingo would make them execute a little faster than the handlers above.

URL: