public RectangleRn WrappingRectangle() { 
            Euler euler = new Euler();
            euler.phi      = phi;
            euler.theta    = theta;
            euler.psi      = psi;
            euler.psi_a    = Euler.AXIS_Z ;
            euler.theta_a  = Euler.AXIS_X;
            euler.phi_a    = Euler.AXIS_Z;
            
            if (FP.zero(length)) {
                Point3D beg3d = new Point3D();
                Point3D end3d = new Point3D();
                euler.transform(beg3d, new Point3D(0.0, 0.0));
                euler.transform(end3d, new Point3D(length, 0.0));
                RectangleRn r = beg3d.toRectangle();
                end3d.addToRectangle(r);
                return r;
            } else { 
                double l, ls, lc;
                Point3D[] v = new Point3D[4];
                Point3D tv = new Point3D();
                l  = length / 2.0; 
                ls = Math.Sin(l);
                lc = Math.Cos(l);
                euler.phi += l;
                
                v[0] = new Point3D(lc,  lc<0 ? -1.0 : -ls, 0.0);
                v[1] = new Point3D(1.0, lc<0 ? -1.0 : -ls, 0.0);
                v[2] = new Point3D(lc,  lc<0 ? +1.0 : +ls, 0.0);
                v[3] = new Point3D(1.0, lc<0 ? +1.0 : +ls, 0.0) ;
 
                Point3D min = new Point3D(1.0, 1.0, 1.0);
                Point3D max = new Point3D(-1.0, -1.0, -1.0);
 
                for (int i=0; i<4; i++) {
                    euler.transform(tv, v[i]);
                    if (tv.x < -1.0) {
                        min.x = -1.0;
                    } else if (tv.x > 1.0) {
                        max.x = 1.0;
                    } else { 
                        if (tv.x < min.x) { 
                            min.x = tv.x;
                        }
                        if (tv.x > max.x) { 
                            max.x = tv.x;
                        }
                    }
                    
                    if (tv.y < -1.0) {
                        min.y = -1.0;
                    } else if ( tv.y > 1.0 ) {
                        max.y = 1.0;
                    } else {
                        if (tv.y < min.y) { 
                            min.y = tv.y;
                        }
                        if (tv.y > max.y) { 
                            max.y = tv.y;
                        }
                    }
                    if (tv.z < -1.0) {
                        min.z = -1.0;
                    } else if (tv.z > 1.0) {
                        max.z = 1.0;
                    } else { 
                        if (tv.z < min.z) { 
                            min.z = tv.z;
                        }
                        if (tv.z > max.z) { 
                            max.z = tv.z;
                        }
                    } 
                }  
                return new RectangleRn(new double[]{min.x, min.y, min.z, max.x, max.y, max.z});
            }
        }
            public RectangleRn WrappingRectangle()
            {
                Euler euler = new Euler();

                euler.phi     = phi;
                euler.theta   = theta;
                euler.psi     = psi;
                euler.psi_a   = Euler.AXIS_Z;
                euler.theta_a = Euler.AXIS_X;
                euler.phi_a   = Euler.AXIS_Z;

                if (FP.zero(length))
                {
                    Point3D beg3d = new Point3D();
                    Point3D end3d = new Point3D();
                    euler.transform(beg3d, new Point3D(0.0, 0.0));
                    euler.transform(end3d, new Point3D(length, 0.0));
                    RectangleRn r = beg3d.toRectangle();
                    end3d.addToRectangle(r);
                    return(r);
                }
                else
                {
                    double    l, ls, lc;
                    Point3D[] v  = new Point3D[4];
                    Point3D   tv = new Point3D();
                    l          = length / 2.0;
                    ls         = Math.Sin(l);
                    lc         = Math.Cos(l);
                    euler.phi += l;

                    v[0] = new Point3D(lc, lc < 0 ? -1.0 : -ls, 0.0);
                    v[1] = new Point3D(1.0, lc < 0 ? -1.0 : -ls, 0.0);
                    v[2] = new Point3D(lc, lc < 0 ? +1.0 : +ls, 0.0);
                    v[3] = new Point3D(1.0, lc < 0 ? +1.0 : +ls, 0.0);

                    Point3D min = new Point3D(1.0, 1.0, 1.0);
                    Point3D max = new Point3D(-1.0, -1.0, -1.0);

                    for (int i = 0; i < 4; i++)
                    {
                        euler.transform(tv, v[i]);
                        if (tv.x < -1.0)
                        {
                            min.x = -1.0;
                        }
                        else if (tv.x > 1.0)
                        {
                            max.x = 1.0;
                        }
                        else
                        {
                            if (tv.x < min.x)
                            {
                                min.x = tv.x;
                            }
                            if (tv.x > max.x)
                            {
                                max.x = tv.x;
                            }
                        }

                        if (tv.y < -1.0)
                        {
                            min.y = -1.0;
                        }
                        else if (tv.y > 1.0)
                        {
                            max.y = 1.0;
                        }
                        else
                        {
                            if (tv.y < min.y)
                            {
                                min.y = tv.y;
                            }
                            if (tv.y > max.y)
                            {
                                max.y = tv.y;
                            }
                        }
                        if (tv.z < -1.0)
                        {
                            min.z = -1.0;
                        }
                        else if (tv.z > 1.0)
                        {
                            max.z = 1.0;
                        }
                        else
                        {
                            if (tv.z < min.z)
                            {
                                min.z = tv.z;
                            }
                            if (tv.z > max.z)
                            {
                                max.z = tv.z;
                            }
                        }
                    }
                    return(new RectangleRn(new double[] { min.x, min.y, min.z, max.x, max.y, max.z }));
                }
            }