// Construct from bounding box mapping:
 FgAffineCwC(
     const FgMatrixC<T,dim,2> & domainBounds,    // Column vectors are lo and hi bounds resp.
     const FgMatrixC<T,dim,2> & rangeBounds)     // "
 {
     FgMatrixC<T,dim,1>
         domainDelta = domainBounds.colVec(1) - domainBounds.colVec(0),
         rangeDelta = rangeBounds.colVec(1) - rangeBounds.colVec(0);
     // Note that the deltas can be negative if the transform inverts an axis:
     FGASSERT(fgNoZeros(domainDelta) && fgNoZeros(rangeDelta));
     for (uint dd=0; dd<dim; ++dd) {
         m_scales[dd] = rangeDelta[dd] / domainDelta[dd];
         m_trans[dd] = rangeBounds.elm(0,dd) - domainBounds.elm(0,dd) * m_scales[dd];
     }
 }
FgMatrixC<T,nrows,1>
fgMaxColwise(const FgMatrixC<T,nrows,ncols> & mat)
{
    FG_STATIC_ASSERT(ncols > 1);
    FgMatrixC<T,nrows,1>    ret(mat.colVec(0));
    for (uint row=0; row<nrows; ++row)
        for (uint col=1; col<ncols; ++col)
            fgSetIfGreater(ret[row],mat.elm(col,row));
    return ret;
}
FgMatrixC<T,dim,2>
fgCubeBounds(const vector<FgMatrixC<T,dim,1> > & verts,T padRatio=1)
{
    FgMatrixC<T,dim,2>  ret;
    FgMatrixC<T,dim,2>  bounds = fgBounds(verts);
    FgMatrixC<T,dim,1>  lo = bounds.colVec(0),
                        hi = bounds.colVec(1),
                        centre = (lo + hi) * T(0.5);
    T                   hsize = fgMaxElem(hi - lo) * 0.5f * padRatio;
    ret = fgConcatHoriz(centre-FgMatrixC<T,dim,1>(hsize),centre+FgMatrixC<T,dim,1>(hsize));
    return ret;
}
 FgAffineCwPreC(
     FgMatrixC<T,dim,2>  domain,
     FgMatrixC<T,dim,2>  range)
 {
     FgMatrixC<T,dim,1>  domainLo = domain.colVec(0),
                         domainHi = domain.colVec(1),
                         domainSize = domainHi-domainLo,
                         rangeLo = range.colVec(0),
                         rangeHi = range.colVec(1),
                         rangeSize = rangeHi-rangeLo;
     FGASSERT(domainSize.volume() > 0);
     m_scales = fgMapDiv(rangeSize,domainSize);
     m_trans = fgMapDiv(rangeLo,m_scales) - domainLo;
 }
FgMatrixC<T,dim,1>
fgBoundsCentre(const std::vector<FgMatrixC<T,dim,1> > & verts)
{
    FgMatrixC<T,dim,2>  bounds = fgBounds(verts);
    return (bounds.colVector[0] + bounds.colVec(1)) * 0.5;
}
FgMatrixC<T,nrows,1>
fgDims(const std::vector<FgMatrixC<T,nrows,1> > & vec)
{
    FgMatrixC<T,nrows,2>    bounds = fgBounds(vec);
    return (bounds.colVec(1)-bounds.colVec(0));
}