15#include "image_processing.h"
16#include "simpleTreeVec.h"
20template<
typename T,
typename P>
21Point_2d subtract(T& p1,P& p2){
22 return Point_2d(p1[0] - p2[0], p1[1] - p2[1]);
25double crossD(P &O,P &A,P &B){
26 return (A[0] - O[0]) * (B[1] - O[1]) - (A[1] - O[1]) * (B[0] - O[0]);
34 if(curve.size() <=3)
return 0;
36 size_t N = curve.size(),count = 0;
39 curve.push_back(curve[0]);
41 for(
size_t i=0;i<N-2;++i){
42 for(
size_t j=i+2;j<N;++j){
43 if(Utilities::Geometry::intersect(curve[i].x,curve[i+1].x,curve[j].x,curve[j+1].x)){
47 std::swap(curve[k] , curve[l]);
66std::vector<Point_2d>
TighterHull(
const std::vector<Point_2d> &v);
69std::vector<Point_2d>
TightestHull(
const std::vector<Point_2d> &v);
173std::vector<Point_2d>
RandomInPoly(std::vector<Point_2d> &pp,
203 ,std::vector<std::vector<P> > &points
204 ,std::vector<bool> &hits_edge
205 ,
bool add_to_vector=
false
206 ,
bool outer_only=
false
209 size_t n = bitmap.size();
213 std::cerr <<
"Wrong sizes in Utilities::find_boundaries." << std::endl;
214 throw std::invalid_argument(
"invalid size");
217 std::vector<bool> not_used(n,
true);
220 for(
size_t i=0 ; i<nx ; ++i) bitmap[i]=
false;
221 size_t j = nx*(ny-1);
222 for(
size_t i=0 ; i<nx ; ++i) bitmap[i + j]=
false;
223 for(
size_t i=0 ; i<ny ; ++i) bitmap[i*nx]=
false;
225 for(
size_t i=0 ; i<ny ; ++i) bitmap[j + i*nx]=
false;
227 std::list<std::list<Point_2d>> contours;
234 long kfirst_in_bound = -1;
239 for( k = kfirst_in_bound + 1 ; k < n - nx ; ++k){
242 if(bitmap[k] ) type +=1;
243 if(bitmap[k+1]) type += 10;
244 if(bitmap[k + nx]) type += 100;
245 if(bitmap[k + nx + 1]) type += 1000;
260 contours.resize(contours.size() + 1);
261 std::list<Point_2d> &contour = contours.back();
262 hits_edge.push_back(
false);
270 while(k != kfirst_in_bound || n_edge==0){
273 std::cerr <<
"Too many points in Utilities::find_boundaries()." << std::endl;
274 std::cerr <<
"kfirst_in_bound " << kfirst_in_bound << std::endl;
275 std::cerr <<
" contour is output to boundary_error_file.csv and bitmap_error_file.csv" << std::endl;
277 std::ofstream file(
"bitmap_error_file.csv");
278 file <<
"in,x,y" << std::endl;
279 for(
size_t i=0 ; i<n ; ++i){
280 file << bitmap[i] <<
"," << i%nx <<
"," << i/nx << std::endl;
285 std::ofstream file(
"boundary_error_file.csv");
286 file <<
"contour,x,y" << std::endl;
288 for(
auto &v : contours){
290 file << i <<
"," << p[0] <<
"," << p[1] << std::endl;
295 throw std::runtime_error(
"caught in loop.");
298 if(k%nx == 0 || k%nx == nx-2) hits_edge.back() =
true;
299 if(k/nx == 0 || k/nx == ny-2) hits_edge.back() =
true;
306 if(bitmap[k]) type +=1;
307 if(bitmap[k+1]) type += 10;
308 if(bitmap[k + nx]) type += 100;
309 if(bitmap[k + nx + 1]) type += 1000;
311 if(type == 0 || type == 1111){
312 throw std::runtime_error(
"off edge!!");
313 }
else if(type == 1 || type == 1110){
316 contour.push_back(
Point_2d( k%nx + 0.5
329 }
else if(type == 10 || type == 1101){
332 contour.push_back(
Point_2d( k%nx + 0.5
338 contour.push_back(
Point_2d( k%nx + 1
345 }
else if(type == 100 || type == 1011){
348 contour.push_back(
Point_2d( k%nx + 0.5
361 }
else if(type == 1000 || type == 111){
364 contour.push_back(
Point_2d( k%nx + 1
370 contour.push_back(
Point_2d( k%nx + 0.5
377 }
else if(type == 11 || type == 1100){
380 contour.push_back(
Point_2d( k%nx + 1
392 }
else if(type == 1010 || type == 101){
395 contour.push_back(
Point_2d( k%nx + 0.5
400 contour.push_back(
Point_2d( k%nx + 0.5
407 }
else if(type == 1001){
410 contour.push_back(
Point_2d( k%nx + 0.5
415 }
else if(face_in==1){
421 }
else if(face_in==2){
422 contour.push_back(
Point_2d( k%nx + 0.5
428 contour.push_back(
Point_2d( k%nx + 1
435 }
else if(type == 110){
438 contour.push_back(
Point_2d( k%nx + 0.5
443 }
else if(face_in==1){
444 contour.push_back(
Point_2d( k%nx + 1
449 }
else if(face_in==2){
450 contour.push_back(
Point_2d( k%nx + 0.5
472 if(outer_only)
break;
477 points.resize(contours.size());
479 offset = points.size();
480 points.resize(points.size() + contours.size());
485 for(
auto &c: contours){
486 points[offset+i].resize(c.size());
489 points[offset+i][j] = p;
499 ,std::vector<std::vector<long> > &indexes
500 ,std::vector<bool> &hits_edge
501 ,
bool add_to_vector=
false
506 ,
const std::vector<Point_2d> &x);
524 std::vector<T> hull(2*n);
527 std::sort(P.begin(), P.end(),
529 if(p1[0]==p2[0]) return p1[1] < p2[1];
530 return p1[0] < p2[0];});
534 for (
size_t i = 0; i < n; i++) {
535 while (k >= 2 && crossD(hull[k-2], hull[k-1], P[i]) <= 0){
542 for (
long i = n-2, t = k+1; i >= 0; i--) {
543 while (k >= t && crossD(hull[k-2], hull[k-1], P[i]) <= 0){
560void convex_hull(
const std::vector<T> &P,std::vector<size_t> &hull)
568 for(
size_t &d : hull) d = i++;
577 std::vector<size_t> sort_index(P.size());
580 for(
size_t &a : sort_index) a = i++;
582 std::sort(sort_index.begin(), sort_index.end(),
583 [&P](
size_t i1,
size_t i2){
584 if(P[i1][0]==P[i2][0]) return P[i1][1] < P[i2][1];
585 return P[i1][0] < P[i2][0];});
589 for (
size_t i = 0; i < n; i++) {
590 while (k >= 2 && crossD(P[hull[k-2]], P[hull[k-1]], P[sort_index[i]]) <= 0){
593 hull[k++] = sort_index[i];
597 for (
long i = n-2, t = k+1; i >= 0; i--) {
598 while (k >= t && crossD(P[hull[k-2]], P[hull[k-1]],P[sort_index[i]]) <= 0){
602 hull[k++] = sort_index[i];
613 Edge(
size_t i,
double l):length(l),index(i){};
634 ,std::vector<T> &hull_out,
double scale)
644 if(init_points.size() == hull.size())
return;
646 std::list<Edge> edges;
647 std::list<T> leftovers;
648 hull.push_back(hull[0]);
653 for(
int i=0;i<hull.size()-1;++i){
654 tmp = (subtract(hull[i],hull[i+1])).length();
655 if(tmp > scale) edges.emplace_back(i,tmp);
658 if(edges.size() == 0)
return;
661 PosType cent[] ={0.5,0.5};
666 map.drawPoints(init_points,0.01,1.0);
667 map.drawCurve(hull,2);
673 edges.sort([](
const Edge &p1,
const Edge &p2){
return p1.length > p2.length;});
674 assert(edges.front().length >= edges.back().length);
680 std::vector<size_t> index(hull.size());
682 for(
size_t &ind: index) ind = i++;
683 std::sort(index.begin(),index.end(),
684 [&hull](
size_t p1,
size_t p2){
685 if(hull[p1][0] == hull[p2][0]) return hull[p1][1] < hull[p2][1];
686 return hull[p1][0] < hull[p2][0];});
690 for(
auto pit = init_points.begin(); pit != init_points.end() ; ++pit){
692 if((hull[index[j]][0] == (*pit)[0])*(hull[index[j]][1] == (*pit)[1])){
695 leftovers.push_back(*pit);
699 assert(hull.size() + leftovers.size() == init_points.size());
700 hull.push_back(hull[0]);
703 typename std::list<T>::iterator p,nextpoint;
706 double minarea,area,co1;
711 while(edges.front().length > scale ){
713 if(leftovers.size() == 0)
break;
717 i = edges.front().index;
719 for(p = leftovers.begin() ; p != leftovers.end() ; ++p){
721 v1 = subtract(*p,hull[i]);
723 if( edges.front().length > v1.
length()){
725 vo = subtract(hull[i+1], hull[i]);
731 if( co1 > 0 && (area > 0)*(area < minarea) ){
739 if(minarea == HUGE_VAL){
747 leftovers.erase(nextpoint);
748 hull.insert(hull.begin() + i + 1,tmp);
751 Edge new1 = edges.front();
753 new1.length = (subtract(hull[i],hull[i+1])).length();
754 Edge new2(i+1,(subtract(hull[i+1],hull[i+2])).length());
756 for(
auto &p : edges)
if(p.index > i) ++(p.index);
758 auto p = edges.begin();
759 if(new1.length > scale){
760 for(p = edges.begin() ; p != edges.end() ; ++p){
761 if((*p).length < new1.length){
762 edges.insert(p,new1);
766 if(p==edges.end()) edges.push_back(new1);
768 if(new2.length > scale){
769 for(p = edges.begin(); p != edges.end() ; ++p){
770 if((*p).length < new2.length){
771 edges.insert(p,new2);
775 if(p==edges.end()) edges.push_back(new2);
780 PosType cent[] ={0.5,0.5};
785 map.drawPoints(init_points,0.03,1.0);
786 map.drawCurve(hull,2);
796 std::swap(hull,hull_out);
802std::vector<T> concave2(std::vector<T> &init_points,
double scale)
812 if(init_points.size() == hull.size())
return hull;
814 std::list<Edge> edges;
815 std::list<T> leftovers;
816 hull.push_back(hull[0]);
821 for(
int i=0;i<hull.size()-1;++i){
822 tmp = (subtract(hull[i],hull[i+1])).length();
823 if(tmp > scale) edges.emplace_back(i,tmp);
826 if(edges.size() == 0)
return hull;
829 PosType cent[] ={0.5,0.5};
830 PixelMap<float> map(cent,256, 1.0/256);
832 map.drawgrid(10,0.5);
834 map.drawPoints(init_points,0.01,1.0);
835 map.drawCurve(hull,2);
837 map.printFITS(
"!test_concave.fits");
841 edges.sort([](
const Edge &p1,
const Edge &p2){
return p1.length > p2.length;});
842 assert(edges.front().length >= edges.back().length);
848 std::vector<size_t> index(hull.size());
850 for(
size_t &ind: index) ind = i++;
851 std::sort(index.begin(),index.end(),
852 [&hull](
size_t p1,
size_t p2){
853 if(hull[p1][0] == hull[p2][0]) return hull[p1][1] < hull[p2][1];
854 return hull[p1][0] < hull[p2][0];});
858 for(
auto pit = init_points.begin(); pit != init_points.end() ; ++pit){
860 if((hull[index[j]][0] == (*pit)[0])*(hull[index[j]][1] == (*pit)[1])){
863 leftovers.push_back(*pit);
867 assert(hull.size() + leftovers.size() == init_points.size());
868 hull.push_back(hull[0]);
871 typename std::list<T>::iterator p,nextpoint;
874 double minarea,area,co1;
878 while(edges.front().length > scale ){
880 if(leftovers.size() == 0)
break;
884 i = edges.front().index;
886 for(p = leftovers.begin() ; p != leftovers.end() ; ++p){
888 v1 = subtract(*p,hull[i]);
890 if( edges.front().length > v1.
length()){
892 vo = subtract(hull[i+1], hull[i]);
898 if( co1 > 0 && (area > 0)*(area < minarea) ){
906 if(minarea == HUGE_VAL){
914 leftovers.erase(nextpoint);
915 hull.insert(hull.begin() + i + 1,tmp);
918 Edge new1 = edges.front();
920 new1.length = (subtract(hull[i],hull[i+1])).length();
921 Edge new2(i+1,(subtract(hull[i+1],hull[i+2])).length());
923 for(
auto &p : edges)
if(p.index > i) ++(p.index);
925 auto p = edges.begin();
926 if(new1.length > scale){
927 for(p = edges.begin() ; p != edges.end() ; ++p){
928 if((*p).length < new1.length){
929 edges.insert(p,new1);
933 if(p==edges.end()) edges.push_back(new1);
935 if(new2.length > scale){
936 for(p = edges.begin(); p != edges.end() ; ++p){
937 if((*p).length < new2.length){
938 edges.insert(p,new2);
942 if(p==edges.end()) edges.push_back(new2);
947 PosType cent[] ={0.5,0.5};
948 PixelMap<float> map(cent,256, 1.0/256);
950 map.drawgrid(10,0.5);
952 map.drawPoints(init_points,0.03,1.0);
953 map.drawCurve(hull,2);
955 map.printFITS(
"!test_concave.fits");
967template <
typename Ptype>
968double distance_to_segment(
const Ptype &P
974 double s = (P-S1)*D / D.length_sqr();
975 if(isnan(s) || s<=0){
976 return (P-S1).length();
978 return (P-S2).length();
980 return (S1 + D*s - P).length();
983template <
typename Ptype>
984double distance_to_segment(
const Ptype &P
987 ,Ptype &closest_point
991 double s = (P-S1)*D / D.length_sqr();
992 if(isnan(s) || s<=0){
997 closest_point = S1 + D*s;
999 return (closest_point - P).length();
1002template <
typename Ptype>
1003bool segments_cross(
const Ptype &a1,
const Ptype &a2
1004 ,
const Ptype &b1,
const Ptype &b2){
1009 double tmp = (db^da);
1010 if(tmp==0)
return false;
1012 double B = (da^d1) / tmp;
1013 if( (B>1) || (B<0))
return false;
1015 if( (B>1) || (B<0))
return false;
1020template <
typename Ptype>
1021bool inCurve(
const Ptype &x,
const std::vector<Ptype> &H){
1022 if(H.size() < 3)
return false;
1026 for(
size_t i=0 ; i<n ; ++i){
1028 if(H[j][1] != H[i][1]){
1029 p1[1] = H[i][1] - x[1];
1030 p2[1] = H[j][1] - x[1];
1031 if( p1[1]*p2[1] < 0 ){
1032 p1[0] = H[i][0] - x[0];
1033 p2[0] = H[j][0] - x[0];
1035 if(p1[0]>=0 && p2[0]>=0){
1036 w += 2*( p1[1] >= 0 ) - 1;
1037 }
else if(p1[0] > 0 || p2[0] > 0){
1038 double s = p1[0] - (p2[0]-p1[0])*p1[1]/(p2[1]-p1[1]);
1040 w += 2*( p1[1] >= 0 ) - 1;
1044 p2[0] = H[j][0] - x[0];
1051 while( H[k][1] - x[1] == 0 && k!=i) k = (k+1)%n;
1053 if(k!=i && p1[1]*( H[k][1] - x[1] ) <= 0){
1054 w += 2*( p1[1] >= 0 ) - 1;
1063template <
typename Ptype>
1064bool inhull(PosType x[],
const std::vector<Ptype> &H){
1066 size_t n = H.size();
1067 if(n <=2)
return false;
1071 for(
size_t i=0 ; i<n-1 ; ++i){
1074 if(x[1] == H[i][1]){
1075 B = (x[0]-H[i][0])/dH[0];
1076 if( B>=0 && B<=1 )
return true;
1079 dD[0] = x[0]-H[i][0];
1080 dD[1] = x[1]-H[i][1];
1082 if( A > 1 || A <= 0)
continue;
1097inline bool inhull<Point *>(PosType x[],
const std::vector<Point *> &H){
1099 size_t n = H.size();
1100 if(n <=2)
return false;
1104 for(
size_t i=0 ; i<n-1 ; ++i){
1107 if(x[1] == H[i]->x[1]){
1108 B = (x[0]-H[i]->x[0])/dH[0];
1109 if( B>=0 && B<=1 )
return true;
1112 dD[0] = x[0]-H[i]->x[0];
1113 dD[1] = x[1]-H[i]->x[1];
1115 if( A > 1 || A <= 0)
continue;
1133 size_t n = H.size();
1134 if(n <=2)
return false;
1138 for(
size_t i=0 ; i<n-1 ; ++i){
1139 dH = H[i+1].x-H[i].x;
1141 if(x[1] == H[i].x[1]){
1142 B = (x[0]-H[i].x[0])/dH[0];
1143 if( B>=0 && B<=1 )
return true;
1146 dD[0] = x[0]-H[i].x[0];
1147 dD[1] = x[1]-H[i].x[1];
1149 if( A > 1 || A <= 0)
continue;
1164inline bool inhull<PosType *>(PosType x[],
const std::vector<PosType *> &H){
1166 size_t n = H.size();
1167 if(n <=2)
return false;
1171 for(
size_t i=0 ; i<n-1 ; ++i){
1172 dH[0] = H[i+1][0]-H[i][0];
1173 dH[1] = H[i+1][1]-H[i][1];
1175 if(x[1] == H[i][1]){
1176 B = (x[0]-H[i][0])/dH[0];
1177 if( B>=0 && B<=1 )
return true;
1180 dD[0] = x[0]-H[i][0];
1181 dD[1] = x[1]-H[i][1];
1183 if( A > 1 || A <= 0)
continue;
1207template <
typename Ptype>
1208std::vector<Ptype>
concaveK(std::vector<Ptype> &points,
int &k,
bool check=
true)
1211 if(points.size() <= 3){
1217 size_t npoints = points.size();
1234 std::vector<Ptype> hull;
1236 double xmin = points[0][0];
1237 size_t first_point_index = 0;
1238 for(
size_t i=0 ; i<npoints ; ++i){
1239 if(points[i][0] < xmin){
1240 xmin = points[i][0];
1241 first_point_index = i;
1245 Ptype firstpoint = points[first_point_index];
1247 std::vector<size_t> remaining_index;
1248 bool segmented =
true;
1255 if(k>=points.size()){
1260 hull.push_back(firstpoint);
1263 std::vector<double> radii;
1264 std::vector<size_t> neighbors;
1265 Ptype hull_end = hull.back();
1268 Ptype last_point = Ptype(hull[0][0],hull[0][1]-1);
1274 std::vector<double> thetas;
1275 std::vector<int> sorted_index(k);
1277 while((hull[0] != hull.back() && found) || hull.size()==1 ){
1281 long Nneighbors = neighbors.size();
1282 thetas.resize(Nneighbors);
1283 sorted_index.resize(Nneighbors);
1285 v1 = hull_end - last_point;
1287 for(
int i=0; i<Nneighbors ; ++i){
1288 v2 = points[neighbors[i]] - hull_end;
1289 double cross = v1^v2,dot = (v1*v2);
1290 if(cross == 0 && dot <= 0) thetas[i] = -PI;
1291 else thetas[i] = atan2( cross , dot );
1292 sorted_index[i] = i;
1295 std::sort(sorted_index.begin(),sorted_index.end()
1296 ,[&thetas](
int i,
int j){return thetas[i] > thetas[j];} );
1299 bool intersect =
true;
1300 while(intersect && trial < Nneighbors){
1302 new_index = neighbors[ sorted_index[trial] ];
1303 new_point = points[ new_index ];
1305 if(hull.size() <= 3) intersect =
false;
1308 for(
long i = hull.size() - 2 ; i > 1 ; --i){
1309 intersect = segments_cross(hull[i],hull[i-1]
1310 ,hull.back(),new_point);
1317 if(new_index == first_point_index && !intersect){
1320 hull.push_back(new_point);
1321 for(
size_t i : neighbors){
1322 if(i != new_index && !
inCurve(points[i],hull)){
1352 hull.push_back(new_point);
1353 last_point = hull_end;
1354 hull_end = hull.back();
1356 tree.
pop(new_index);
1378 for(
auto i : remaining_index){
1409template <
typename Ptype>
1411 std::vector<Ptype> points(200);
1412 RandomNumbers_NR ran(2312);
1414 for(Ptype &p : points){
1420 for(
int i=0 ; i< points.size()/4 ; ++i){
1426 for(
int i=points.size()/4 ; i< 2*points.size()/4 ; ++i){
1432 for(
int i=2*points.size()/4 ; i< 3*points.size()/4 ; ++i){
1438 for(
int i=3*points.size()/4 ; i< points.size() ; ++i){
1459 std::vector<Ptype> hull =
concaveK(points,k);
1461 PixelMap<float> map(center.x, 512, 3. / 512.);
1463 map.drawCurve(hull,1);
1464 map.drawPoints(points,0,2);
1465 map.printFITS(
"!concavek_test.fits");
1466 std::cout <<
"Test plot : concavek_test.fits" << std::endl;
1471 const Point_2d &w1,
const Point_2d &w2);
1489std::vector<Point_2d>
envelope(
const std::vector<Point_2d> &v
1490 ,
const std::vector<Point_2d> &w);
1497std::vector<Point_2d>
envelope2(
const std::vector<Point_2d> &v
1498 ,
const std::vector<Point_2d> &w);
1508 const std::vector<Point_2d> &v
Image structure that can be manipulated and exported to/from fits files.
Definition pixelmap.h:42
void printFITS(std::string filename, bool Xflip=false, bool ctype=false, bool verbose=false)
Output the pixel map as a fits file.
Definition pixelmap.cpp:1318
void drawgrid(int N, PosType value)
draw a grid on the image that divides the each demension into N cells
Definition pixelmap.cpp:1717
A tree for doing quick searches in multidimensional space. A pointer to an array of objects type T is...
Definition simpleTreeVec.h:22
void pop(IndexType index_of_point)
pop this point out of the tree
Definition simpleTreeVec.h:61
std::vector< IndexType > get_index() const
returns the index numbers of the remaining points which are less than the original if pop() was used.
Definition simpleTreeVec.h:105
void NearestNeighbors(D *ray, int Nneighbors, std::vector< D > &radii, std::vector< IndexType > &neighbors)
Finds the nearest N neighbors and puts their index numbers in an array, also returns the distance to ...
Definition simpleTreeVec.h:464
This is a class for generating random numbers. It simplifies and fool proofs initialization and allow...
Definition utilities_slsim.h:1059
Definition utilities.h:39
size_t RemoveIntersections(std::vector< T > &curve)
removes the intersections of the curve
Definition concave_hull.h:32
Point_2d RandomInPoly(std::vector< Point_2d > &pp, Utilities::RandomNumbers_NR &ran)
return a point within a polygon that doesn't need to be convex
Definition curve_routines.cpp:3667
void find_boundaries(std::vector< bool > &bitmap, long nx, std::vector< std::vector< P > > &points, std::vector< bool > &hits_edge, bool add_to_vector=false, bool outer_only=false)
finds ordered boundaries to regions where bitmap == true
Definition concave_hull.h:201
double interior_mass(const std::vector< Point_2d > &alpha, const std::vector< Point_2d > &x)
this returns area within the curve x average kappa iwithin the curve
Definition curve_routines.cpp:2078
std::vector< Point_2d > envelope(const std::vector< Point_2d > &v, const std::vector< Point_2d > &w)
Find a curve that is made up of segments from v and w that surrounds them and does not self intersect...
Definition curve_routines.cpp:3126
void concave(std::vector< T > &init_points, std::vector< T > &hull_out, double scale)
Creates the concave hull of a group of 2 dimensional points by the shrink-wrap algorithm.
Definition concave_hull.h:633
std::vector< Point_2d > TighterHull(const std::vector< Point_2d > &v)
Definition curve_routines.cpp:3275
bool inhull< RAY >(PosType x[], const std::vector< RAY > &H)
finds in x is within the curve discribed by the H[].x points ie image points
Definition concave_hull.h:1131
std::vector< Point_2d > envelope2(const std::vector< Point_2d > &v, const std::vector< Point_2d > &w)
Find a curve that is made up of segments from v and w that surrounds them and does not self intersect...
Definition curve_routines.cpp:3067
std::vector< std::vector< Point_2d > > thicken_poly(const std::vector< Point_2d > &v, double R)
return the boundaries of the region that is within R of the curve v
Definition curve_routines.cpp:2966
Point_2d RandomInTriangle(const Point_2d &x1, const Point_2d &x2, const Point_2d &x3, Utilities::RandomNumbers_NR &ran)
returns random point within a trinagle
Definition curve_routines.cpp:3600
std::vector< Ptype > concaveK(std::vector< Ptype > &points, int &k, bool check=true)
Definition concave_hull.h:1208
std::vector< T > convex_hull(const std::vector< T > &PP)
Returns a vector of points on the convex hull in counter-clockwise order.
Definition concave_hull.h:513
std::vector< Point_2d > TightestHull(const std::vector< Point_2d > &v)
Finds a concave envelope for an arbitrary closed curve. This is done by gridding and then finding poi...
Definition curve_routines.cpp:3519
Point_2d RandomInConvexPoly(const std::vector< Point_2d > &pp, Utilities::RandomNumbers_NR &ran)
return a point within a convex polygon
Definition curve_routines.cpp:3614
void find_islands(std::vector< bool > &bitmap, long nx, std::vector< std::vector< long > > &indexes, std::vector< bool > &hits_edge, bool add_to_vector=false)
find the indexes of areas with bitmap[]=true broken up into diconnected islands
Definition curve_routines.cpp:2670
bool circleOverlapsCurve(const Point_2d &x, double r, const std::vector< Point_2d > &v)
Returns true if there is any overlap between a curve and a circle. This includea cases where one comp...
Definition curve_routines.cpp:2955
Point_2d line_intersection(const Point_2d &v1, const Point_2d &v2, const Point_2d &w1, const Point_2d &w2)
return the interesetion point of line defined by v1,v2 and w1,w2
Definition curve_routines.cpp:2928
Point_2d RandomNearPoly(std::vector< Point_2d > &pp, double R, Utilities::RandomNumbers_NR &ran)
return a point within distance R of a polygon, i.e. the center of a cicle that intersects the interio...
Definition curve_routines.cpp:3737
bool circleIntersetsCurve(const Point_2d &x, double r, const std::vector< Point_2d > &v)
returns true if a circle of radius r around the point x intersects with the curve v....
Definition curve_routines.cpp:2936
bool inCurve(const Ptype &x, const std::vector< Ptype > &H)
returns true if x is within the polygon H
Definition concave_hull.h:1021
Class for representing points or vectors in 2 dimensions. Not that the dereferencing operator is over...
Definition point.h:48
PosType length() const
length
Definition point.h:134