void PatchSample::sample_frustum(double hfov, double vfov, int nh, int nv, Vector3d p, Vector3d u, MatrixXd &mx, MatrixXd &my, MatrixXd &mz) { //TBD: check input args // pointing, up, left p = p/p.norm(); u = u/u.norm(); Vector3d l = u.cross(p); // sample like a camera would double ll = (tan(hfov/2.0)*((double)(nh-1)))/nh; double uu = (tan(vfov/2.0)*((double)(nv-1)))/nv; RowVectorXd y; y.setLinSpaced(nh,-ll,ll); MatrixXd yy; yy = y.replicate(nv,1); VectorXd z; z.setLinSpaced(nv,-uu,uu); MatrixXd zz; zz = z.replicate(1,nh); MatrixXd xx = MatrixXd::Ones(nv,nh); MatrixXd nn = (xx.array().square() + yy.array().square() + zz.array().square()).cwiseSqrt(); xx = xx.array() / nn.array(); yy = yy.array() / nn.array(); zz = zz.array() / nn.array(); // rotation matrix Matrix3d rr; rr << p, l, u; // rotate points MatrixXd xyz; MatrixXd cam (3,xx.rows()*xx.cols()); cam.row(0) = vectorizeColWise(xx); cam.row(1) = vectorizeColWise(yy); cam.row(2) = vectorizeColWise(zz); xyz = rr*cam; // extract coordinates xx = xyz.row(0); yy = xyz.row(1); zz = xyz.row(2); mx = Map<MatrixXd>(xx.data(),nv,nh); my = Map<MatrixXd>(yy.data(),nv,nh); mz = Map<MatrixXd>(zz.data(),nv,nh); }