public void RotateAboutLine(clsLine3d l1, double theta)
        {
            clsPoint3d p1  = default(clsPoint3d);
            clsPoint3d p2  = default(clsPoint3d);
            clsPoint3d p2a = default(clsPoint3d);
            clsPoint3d p2b = default(clsPoint3d);
            clsPoint3d p3  = default(clsPoint3d);
            clsLine3d  l2  = default(clsLine3d);

            if (l1.IsOnLine(this))
            {
                return;
            }

            //Setup a coordinate system with X running along l1 and the origin at l1.p2
            l2        = new clsLine3d(l1.P2.Copy(), Copy());
            p1        = new clsPoint3d(l1.DX(), l1.DY(), l1.DZ());
            p1.Length = 1;
            p2        = new clsPoint3d(l2.DX(), l2.DY(), l2.DZ());
            p2a       = new clsPoint3d(l2.DX(), l2.DY(), l2.DZ());
            p2.Length = 1;
            p3        = p1.Cross(p2);
            p3.Length = 1;
            p2        = p1.Cross(p3);
            p2.Length = 1;
            if (p2.Dot(p2a) < 0)
            {
                p2.Scale(-1);
            }

            p2b = new clsPoint3d(p1.Dot(p2a), p2.Dot(p2a), p3.Dot(p2a));
            p2b.RotateAboutX(theta);

            myX = l1.X2 + p2b.x * p1.x + p2b.y * p2.x + p2b.z * p3.x;
            myY = l1.Y2 + p2b.x * p1.y + p2b.y * p2.y + p2b.z * p3.y;
            myZ = l1.Z2 + p2b.x * p1.z + p2b.y * p2.z + p2b.z * p3.z;
        }