// 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)); }