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:

Reads:
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 M
M002 XEQ U001
M003 STO E
M004 X<>Y
M005 STO D
M006 -
M007 RCL B
M008 RCL- A
M009 eq [REGXxREGX,REGXxREGY,REGYxREGY]
M010 STO Z
M011 RDN
M012 RCL A
M013 RCL- D
M014 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<>Y
M018 ABS
M019 1E-6
MO20 X>Y?
M021 GOTO M041
M022 RDN
M023 RDN
M024 LASTX
M025 /
M026 eq ([1,0,0]xZ)x([0,1]xREGY)-([0,1,0]xZ)x([1,0]xREGY)
M027 LASTX
MO28 /
M029 X<>Y
M030 4
M031 STO I
M032 RDN
M033 RCL(I)
M034 ABS
M035 RDN
M036 RCL D
M037 RCL E
M038 RDN
M039 RDN
M040 RTN
M041 SF 10
M042 eq PARALELL
M043 PSE
M044 CF 10
M045 XEQ U029
M046 RTN
Comments:

Terms of use.

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:

Reads:
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 F
F002 ABS
F003 RDN
F004 (1-LASTX)xD+LASTXxE
F005 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!.

No comments: