public Line(Point beg, Point end)
            {
                double l = beg.Distance(end);

                if (FP.eq(l, Math.PI))
                {
                    Debug.Assert(FP.eq(beg.ra, end.ra));
                    phi    = -Math.PI / 2;
                    theta  = Math.PI / 2;
                    psi    = beg.ra < 0.0 ? Math.PI * 2 + beg.ra : beg.ra;
                    length = Math.PI;
                    return;
                }
                if (beg.Equals(end))
                {
                    phi    = Math.PI / 2;
                    theta  = beg.dec;
                    psi    = beg.ra - Math.PI / 2;
                    length = 0.0;
                }
                else
                {
                    Point3D beg3d = new Point3D(beg);
                    Point3D end3d = new Point3D(end);
                    Point3D tp    = new Point3D();
                    Point   spt   = beg3d.cross(end3d).toSpherePoint();
                    Euler   euler = new Euler();
                    euler.phi     = -spt.ra - Math.PI / 2;
                    euler.theta   = spt.dec - Math.PI / 2;
                    euler.psi     = 0.0;
                    euler.psi_a   = Euler.AXIS_Z;
                    euler.theta_a = Euler.AXIS_X;
                    euler.phi_a   = Euler.AXIS_Z;
                    euler.transform(tp, beg3d);
                    spt = tp.toSpherePoint();

                    // invert
                    phi    = spt.ra;
                    theta  = -euler.theta;
                    psi    = -euler.phi;
                    length = l;
                }
            }
         public Line(Point beg, Point end) { 
             double l = beg.Distance(end);
             if (FP.eq(l, Math.PI)) {
                 Debug.Assert(FP.eq(beg.ra, end.ra));
                 phi = -Math.PI/2;
                 theta = Math.PI/2;
                 psi = beg.ra < 0.0 ? Math.PI*2 + beg.ra : beg.ra;
                 length = Math.PI;
                 return;
             }
             if (beg.Equals(end)) { 
                 phi    = Math.PI/2;
                 theta  = beg.dec;
                 psi    = beg.ra - Math.PI/2;
                 length = 0.0;
             } else { 
                 Point3D beg3d = new Point3D(beg);
                 Point3D end3d = new Point3D(end);
                 Point3D tp = new Point3D();
                 Point spt = beg3d.cross(end3d).toSpherePoint();
                 Euler euler = new Euler();
                 euler.phi     = - spt.ra - Math.PI/2;
                 euler.theta   =   spt.dec - Math.PI/2;
                 euler.psi     =   0.0 ;
                 euler.psi_a   = Euler.AXIS_Z;
                 euler.theta_a = Euler.AXIS_X;
                 euler.phi_a   = Euler.AXIS_Z;
                 euler.transform(tp, beg3d);
                 spt = tp.toSpherePoint();
 
                 // invert
                 phi = spt.ra;
                 theta = -euler.theta;
                 psi = -euler.phi;
                 length = l;
             }
         }