FgMatrixC<T,dim,ncols> operator*(const FgMatrixC<T,dim,ncols> & vec) const { FgMatrixC<T,dim,ncols> ret; for (uint row=0; row<dim; ++row) for (uint col=0; col<ncols; ++col) ret.elm(col,row) = m_scales[row] * (vec.elm(col,row) + m_trans[row]); return ret; }
FgMatrixC<T,dim,2> fgBoundsIntersection( const FgMatrixC<T,dim,2> & b1, const FgMatrixC<T,dim,2> & b2) { FgMatrixC<T,dim,2> ret(b1); for (uint dd=0; dd<dim; ++dd) { fgSetIfGreater(ret.elm(0,dd),b2.elm(0,dd)); fgSetIfLess(ret.elm(1,dd),b2.elm(1,dd)); } return ret; }
// 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,dim,2> fgBounds( const FgMatrixC<T,dim,1> & v0, const FgMatrixC<T,dim,1> & v1, const FgMatrixC<T,dim,1> & v2) { FgMatrixC<T,dim,2> ret; for (uint dd=0; dd<dim; ++dd) { ret.elm(0,dd) = ret.elm(1,dd) = v0[dd]; fgSetIfLess(ret.elm(0,dd),v1[dd]); fgSetIfLess(ret.elm(0,dd),v2[dd]); fgSetIfGreater(ret.elm(1,dd),v1[dd]); fgSetIfGreater(ret.elm(1,dd),v2[dd]); } return ret; }
bool fgBoundsIntersect( const FgMatrixC<T,dim,2> & bnds1, const FgMatrixC<T,dim,2> & bnds2, FgMatrixC<T,dim,2> & retval) { FgMatrixC<T,dim,2> tmp; for (uint dd=0; dd<dim; ++dd) { tmp.elm(0,dd) = std::max(bnds1.elm(0,dd),bnds2.elm(0,dd)); tmp.elm(1,dd) = std::min(bnds1.elm(1,dd),bnds2.elm(1,dd)); if (tmp.elm(0,dd) > tmp.elm(1,dd)) return false; } retval = tmp; return true; }
FgAffineC<T,dim> asAffine() const { FgMatrixC<T,dim,dim> scales; for (uint ii=0; ii<dim; ++ii) scales.elm(ii,ii) = m_scales[ii]; return FgAffineC<T,dim>(scales,m_trans); }
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; }
bool fgBoundsIncludes( const FgMatrixC<T,dim,2> & inclusiveBounds, const FgMatrixC<T,dim,1> & point) { for (uint dd=0; dd<dim; ++dd) { if ((inclusiveBounds.elm(1,dd) < point[dd]) || (inclusiveBounds.elm(0,dd) > point[dd])) return false; } return true; }
FgMatrixC<T,dim,2> fgBounds(const std::vector<FgMatrixC<T,dim,1> > & data) { FGASSERT(data.size() > 0); FgMatrixC<T,dim,2> ret; ret.setSubMatrix(data[0],0,0); ret.setSubMatrix(data[0],0,1); for (size_t ii=1; ii<data.size(); ++ii) { for (uint dd=0; dd<dim; ++dd) { fgSetIfLess (ret.elm(0,dd),data[ii][dd]); fgSetIfGreater (ret.elm(1,dd),data[ii][dd]); } } return ret; }