Skip to navigation

Maths (Geometry): GetHypotenuse

Name: GetHypotenuse [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Calculate the hypotenuse from an angle and two triangle sides with one lookup and one multiplication (so without a square root)
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * GetObjectAngles calls GetHypotenuse * GetObjPointAngles calls GetHypotenuse * GetTileViewAngles (Part 1 of 4) calls GetHypotenuse

This routine calculates: hypotenuse(Hi Lo) = a(Hi Lo) + tan(theta / 2) * b(Hi Lo) for a triangle with angle theta, adjacent side a and opposite side b.
Arguments: angleTangent The triangle angle theta a(Hi Lo) The length of a, the adjacent side of the triangle b(Hi Lo) The length of b, the opposite side of the triangle
Returns: Y Y is preserved hypotenuse(Hi Lo) The length of the hypotenuse
.GetHypotenuse STY yStoreHypotenuse \ Store Y in yStoreHypotenuse so it can be preserved \ across calls to the routine LDA angleTangent \ Set Y = angleTangent / 2 LSR A \ ADC #0 \ The ADC instruction rounds the result to the nearest TAY \ integer \ \ The value of angleTangent ranges from 0 to 255 to \ represent the tangent of angles 0 to 45 degrees, but \ the tanHalfAngle table ranges from 0 to 128 to \ represent the same range of angles, so we have to \ halve angleTangent so we can use it as an index into \ the tanHalfAngle table to fetch the tangent of the \ half angle LDA tanHalfAngle,Y \ Set U = 2 * tan(theta / 2) STA U LDA bLo \ Set (V T) = b(Hi Lo) STA T LDA bHi STA V JSR Multiply8x16 \ Set (U T) = U * (V T) / 256 \ = 2 * tan(theta / 2) * b(Hi Lo) LSR U \ Set (U T) = (U T) / 2 ROR T \ = tan(theta / 2) * b(Hi Lo) LDA T \ Calculate: CLC \ ADC aLo \ hypotenuse(Hi Lo) STA hypotenuseLo \ LDA U \ = a(Hi Lo) + (U T) ADC aHi \ STA hypotenuseHi \ = a(Hi Lo) + tan(theta / 2) * b(Hi Lo) LDY yStoreHypotenuse \ Restore the value of Y from yStoreHypotenuse that we \ stored at the start of the routine, so that it's \ preserved RTS \ Return from the subroutine