cv::Mat createPointTarget(cv::Point p, cv::Size s, double sigma) { cv::Mat xv = arange(s.width) - p.x; cv::Mat yv = arange(s.height) - p.y; double scale = 1.0/(sigma*sigma); cv::Mat nxv; cv::Mat nyv; cv::pow(xv,2,nxv); cv::pow(yv,2,nyv); cv::exp(-scale*nxv,nxv); cv::exp(-scale*nyv,nyv); nyv = nyv.reshape(0,1*s.height); //nxv = nxv.reshape(0,s.width); //cv::Mat result = nyv*nxv; //std::cout << "X " << nxv.cols << " " << nxv.rows << " " << nxv.channels() << std::endl; //std::cout << "Y " << nyv.cols << " " << nyv.rows << " " << nyv.channels() << std::endl; //cv::imshow("X",nxv); //cv::imshow("Y",nyv); //cv::imshow("Res",result); //cv::waitKey(); return nyv*nxv; // Works a bit different than python implementation, but result enough similar }
Nested<CircleArc> canonicalize_circle_arcs(Nested<const CircleArc> polys) { // Find the minimal point in each polygon under lexicographic order Array<int> mins(polys.size()); for (int p=0;p<polys.size();p++) { const auto poly = polys[p]; for (int i=1;i<poly.size();i++) if (lex_less(poly[i].x,poly[mins[p]].x)) mins[p] = i; } // Sort the polygons struct Order { Nested<const CircleArc> polys; RawArray<const int> mins; Order(Nested<const CircleArc> polys, RawArray<const int> mins) : polys(polys), mins(mins) {} bool operator()(int i,int j) const { return lex_less(polys(i,mins[i]).x,polys(j,mins[j]).x); } }; Array<int> order = arange(polys.size()).copy(); sort(order,Order(polys,mins)); // Copy into new array Nested<CircleArc> new_polys(polys.sizes().subset(order).copy(),uninit); for (int p=0;p<polys.size();p++) { const int base = mins[order[p]]; const auto poly = polys[order[p]]; const auto new_poly = new_polys[p]; for (int i=0;i<poly.size();i++) new_poly[i] = poly[(i+base)%poly.size()]; } return new_polys; }
char test_spike_l() { double example[20]; size_t i=0; signed char output[20]; printf("test_spike_l simple... "); arange(example,20); for(i=0;i<20;i++) output[i] = 1; example[0] = 100.0; /* Make a spike at the beginning */ example[19] = 100.0; /* Make a spike at the end */ example[10] = 100.0; /* Make a spike in the middle */ spike(output, example, 20, 3, 5, 0.1); if(all(output,20)) return 0; for(i=0;i<20;i++) { if(i==0 || i==19 || i==10) { if(output[i]!=0) return 0; } else { if(output[i]!=1) return 0; } } return 1; }
Eigen::ArrayXXd mpFlow::math::circularPoints(double const radius, double const distance, double const offset, bool const invertDirection, Eigen::Ref<Eigen::ArrayXd const> const midpoint) { Eigen::ArrayXd const phi = arange(offset / radius, offset / radius + 2.0 * M_PI, distance / radius); Eigen::ArrayXXd result = Eigen::ArrayXXd::Zero(phi.rows(), 2); result.col(0) = midpoint(0) + radius * phi.cos(); result.col(1) = midpoint(1) + (invertDirection ? -1.0 : 1.0) * radius * phi.sin(); return result; }
types::ndarray<T, 1> arange(T end) { return arange(T(0), end); }
types::ndarray<double, types::pshape<long>> linspace(double start, double stop, long num, bool endpoint) { double step = (stop - start) / (num - (endpoint ? 1 : 0)); return arange(start, stop + (endpoint ? step * .5 : 0), step); }