## Sunday, September 23, 2007

### HP-35s Euclid Implementation - VI : Closest points on two lines

The following program addresses problem 7 and 8 in the requirements, it finds the closest points on two non paralell lines or tells if the lines are paralell. In 2D non paralell lines intersect so if working in 2D this finds the intersection point. For 3D lines the two points found defines the shortest line segment between two non paralell lines. The length of this line segment is the shortest distance between the lines. Ofcourse 3D lines can intersect: The two points found are then the same point.

The first line has been entered using the L program (refered to as l) and the second is given as first point in the Y stack register and the second in the X stack register (refered to as m).

Stack Input/Output:
`[[x1, y1, z1], [x0, y0, z0], Z, T | L]-> XEQ M ->[s, t, [x1, y1, z1], [x0, y0, z0] | L]`
Where (x0, y0, z0) is the first point defining m, (x1, y1, z1) is the second point defining m, s is the parameter defining the closest point on l to m and t is the parameter defining the closest point on m to l.

If the lines are paralell the message PARALELL is shortly displayed. The stack and LASTX registers are left unchanged in this case.

Variables:

`A : 'First' line l's first defining point.B : 'Second' line l's first defining point.`
Writes:
`D : 'Second' line m's first defining point.E : 'Second' line m's second defining point.Z : Scratch data.`
Program:
`M001 LBL MM002 XEQ U001M003 STO EM004 X<>YM005 STO DM006 -M007 RCL BM008 RCL- AM009 eq [REGXxREGX,REGXxREGY,REGYxREGY]M010 STO ZM011 RDNM012 RCL AM013 RCL- DM014 eq [REGYxREGX,REGZxREGX]M015 eq ([1,0,0]xZ)x([0,0,1]xZ)-([0,1,0]xZ)x([0,1,0]xZ)M016 eq ([0,1,0]xZ)x([0,1]xREGY)-([0,0,1]xZ)x([1,0]xREGY)M017 X<>YM018 ABSM019 1E-6MO20 X>Y?M021 GOTO M041M022 RDNM023 RDNM024 LASTXM025 /M026 eq ([1,0,0]xZ)x([0,1]xREGY)-([0,1,0]xZ)x([1,0]xREGY)M027 LASTXMO28 /M029 X<>YM030 4M031 STO IM032 RDNM033 RCL(I)M034 ABSM035 RDNM036 RCL DM037 RCL EM038 RDNM039 RDNM040 RTNM041 SF 10M042 eq PARALELLM043 PSEM044 CF 10M045 XEQ U029M046 RTN`

If end user needs the coordinates for the closest point on l to m she need only do XEQ E. The M program actual stores the defining points for the m line in variables D (first point) and E (second point) so that with the following short program similar to the E program the coordinate for the closest point on line m to line l can be calculated by moving the parameter for the m line to the X register and do XEQ F:

Stack Input/Output:
`3D case: [t, Y, Z, T | L]-> XEQ F ->[[x, y, z], Y, Z, T | t]2D case: [t, Y, Z, T | L]-> XEQ F ->[[x, y], Y, Z, T | t]`
Where t is the parameter and (x, y, z) is the evaluated point if a 3D line has been entered using the M program and (x, y) is the evaluated point if a 2D line has been entered using the M program.

Variables:

`D: First point defining the line, populated by the M program.E: Second point defining the line, populated by the M program.`
Program:
`F001 LBL FF002 ABSF003 RDNF004 (1-LASTX)xD+LASTXxEF005 RTN`
Mnemonics: Like the L program the program M stores a line (but the implicit equation constants are not computed for this 'secondary' line) so is put next to the L key. Same for the F program: Put next to the E program (that compute coordinates on l).

Allowed one variable to be used for scratch data: The Z variable register.

Change history:

20070929:2035UTC : Change because of fix in U program.
20071002:1835UTC : Bug fix: Did not take absolute value of denominator value when doing epsilon-zero test!.