// check via cross products around A, B, and C with other vertices and Point
// if Point lies in the triangle, the cross products (in a fixed right-hand rule orientation) should have the same sign
bool isTriangle(vector<Point2f> triangle, double i, double j)
{
    Point2f AB = triangle[1]-triangle[0];
    Point2f AP = Point2f(i,j) - triangle[0];
    Point2f BC = triangle[2] - triangle[1];
    Point2f BP = Point2f(i,j) - triangle[1];
    Point2f CA = triangle[0] - triangle[2];
    Point2f CP = Point2f(i,j) - triangle[2];
    
    int sABAP_ABAC = signer(AB.x, AB.y, AP.x, AP.y, -CA.x, -CA.y);
    int sBCBP_BCBA = signer(BC.x, BC.y, BP.x, BP.y, -AB.x, -AB.y);
    int sCACP_CACB = signer(CA.x, CA.y, CP.x, CP.y, -BC.x, -BC.y);
    
    if (sABAP_ABAC >= 0 && sBCBP_BCBA >= 0 && sCACP_CACB >= 0)
        return true;
    
    double crossABAP = cross2d(AB.x, AB.y, AP.x, AP.y);
    double crossBCBP = cross2d(BC.x, BC.y, BP.x, BP.y);
    double crossCACP = cross2d(CA.x, CA.y, CP.x, CP.y);
    
    // if two cross products are 0, inside
    if (((crossABAP >= -tEPSILON && crossABAP <= tEPSILON)
          && (crossBCBP >= -tEPSILON && crossBCBP <= tEPSILON)) ||
        ((crossABAP >= -tEPSILON && crossABAP <= tEPSILON)
         && (crossCACP >= -tEPSILON && crossCACP <= tEPSILON)) ||
        ((crossCACP >= -tEPSILON && crossCACP <= tEPSILON)
         && (crossBCBP >= -tEPSILON && crossBCBP <= tEPSILON)))
        return true;
    
    // if one cross product is 0, the other two equal each other, inside
    if (((crossABAP >= -tEPSILON && crossABAP <= tEPSILON) &&
         (crossBCBP <= crossCACP + tEPSILON && crossBCBP >= crossCACP-tEPSILON)) ||
        ((crossBCBP >= -tEPSILON && crossBCBP <= tEPSILON) &&
         (crossABAP <= crossCACP + tEPSILON && crossABAP >= crossCACP-tEPSILON)) ||
        ((crossCACP >= -tEPSILON && crossCACP <= tEPSILON) &&
         (crossBCBP <= crossABAP + tEPSILON && crossBCBP >= crossABAP-tEPSILON)))
        return true;
    
    //if (i <= faceIm_0.rows || j <= faceIm_0.cols)
    //    return true;
    
    return false;
}
const std::vector<Point*> generateConvexHull2d(std::vector<Point*> points)
{
    int n = (int)points.size();
    std::vector<Point*> hullPoints(2*n);
    int k = 0;
    
    // build lower half
    for (int i = 0; i < n; i++) {
        // while there are at least 2 points in the array and the sequence of those points and
        // point[i] does not make a anti-clockwise turn
        while (k >= 2 && cross2d(hullPoints[k-2], hullPoints[k-1], points[i]) <= 0) {
            k--;
        }
        
        hullPoints[k] = points[i];
        k++;
    }
    
    // build upper half
    for (int i = n-2, t = k+1; i >= 0; i--) {
        // while there are at least 2 points in the array and the sequence of those points and
        // point[i] does not make a anti-clockwise turn
        while (k >= t && cross2d(hullPoints[k-2], hullPoints[k-1], points[i]) <= 0) {
            k--;
        }
        
        hullPoints[k] = points[i];
        k++;
    }
    
    hullPoints.resize(k);
    
    for (int i = 0; i < (int)hullPoints.size(); i++) {
        hullPoints[i]->onHull = true;
    }
    
    return hullPoints;
}
Example #3
0
std::vector<Eigen::Vector3d> generateConvexHull(std::vector<Eigen::Vector3d>& positions)
{
    // Andrew's Monotone Chain Algorithm
    std::sort(positions.begin(), positions.end(), comparePoints);
    
    int n = (int)positions.size();
    std::vector<Eigen::Vector3d> hullPoints(2*n);
    int k = 0;
    
    // build lower half
    for (int i = 0; i < n; i++) {
        // while there are at least 2 points in the array and the sequence of those points and
        // point[i] does not make a anti-clockwise turn
        while (k >= 2 &&
               cross2d(hullPoints[k-2], hullPoints[k-1], positions[i]) <= 0) {
            k--;
        }
        
        hullPoints[k++] = positions[i];
    }
    
    // build upper half
    for (int i = n-2, t = k+1; i >= 0; i--) {
        // while there are at least 2 points in the array and the sequence of those points and
        // point[i] does not make a anti-clockwise turn
        while (k >= t &&
               cross2d(hullPoints[k-2], hullPoints[k-1], positions[i]) <= 0) {
            k--;
        }
        
        hullPoints[k++] = positions[i];
    }
    
    hullPoints.resize(k);
    return hullPoints;
}
float angle2d(const cocos2d::Vec2& a, const cocos2d::Vec2& b){
	return atan2(cross2d(a,b),Vec2::dot(a,b));
}
int read_bc_from_file(
		      struct All_variables *E,
		      standard_precision * field,
		      unsigned int *flags,
		      char *name,
		      char *abbr,
		      unsigned int ON,
		      unsigned int OFF
		      )
{
    int input_string();

    standard_precision cross2d();

    char discard[5001];
    char * token;
 
    char *filename;
    char *input_token;
    FILE *fp;
    int fnodesx,fnodesz,fnodesy;
    int i,j,k,node2d,node3d,column,found;
    int interpolate=0;
    double value;

    standard_precision *T;
    standard_precision yloc;
    char instring[500];

    filename=(char *)Malloc0(500*sizeof(char));
    input_token=(char *)Malloc0(1000*sizeof(char));

    /* Define field name, read parameter file to determine file name and column number */

    sprintf(input_token,"%s_bc_file",name);
    if(!input_string(input_token,filename,"initialize")) {
	fprintf(E->fp,"No %s bc information found in input file\n",name);fflush(E->fp);
	return(0);   /* if not found, take no further action, return zero */
    }

    fprintf(E->fp,"%s bc information is in file %s\n",name,filename);fflush(E->fp);
 
    /* Try opening the file, fatal if this fails too */

    if((fp=fopen(filename,"r")) == NULL) {
	fprintf(E->fp,"Unable to open the required file `%s'\n",filename);fflush(E->fp);
	if(E->control.verbose)
	   	fprintf(stderr,"Unable to open the required file `%s'\n",filename);
	return(0);
    }

     /* Read header, get nodes xzy */

    fgets(discard,4999,fp);
    fgets(discard,4999,fp); 
    i=sscanf(discard,"# NODESX=%d NODESZ=%d NODESY=%d",&fnodesx,&fnodesz,&fnodesy);
    if(i<3) {
	fprintf(E->fp,"File %s is not in the correct format\n",filename);fflush(E->fp);
	return(0);
    }

    fgets(discard,4999,fp); /* largely irrelevant line */
    fgets(discard,4999,fp);
    
    /* This last line is the column headers, we need to search for the occurence of abbr to
       find out the column to be read in. */
    if(!strtok(discard,"|")) { 
	fprintf(E->fp,"Unable to decipher the columns in the input file");fflush(E->fp);
	return(0);
    }

    found=0;
    column=1;

    while(found==0 && (token=(char *)strtok(NULL,"|"))) {
	if(strstr(token,abbr)!=0) found=1;
	column++; 
    }

    if(found) {
	fprintf(E->fp,"\t%s (%s) found in column %d\n",name,abbr,column);fflush(E->fp);
    }    
    else {
	fprintf(E->fp,"\t%s (%s) not found in file: %s\n",name,abbr,filename);fflush(E->fp);
	return(0);
    }

    /* A fatal condition - file size is all wrong */
    if(fnodesx != E->mesh.nox || fnodesz != E->mesh.noz || fnodesy != E->mesh.noy ) {
	fprintf(E->fp,"Input data for file `%s' is not %d x %d x %d\n",
		filename,E->mesh.nox,E->mesh.noz,E->mesh.noy);
	fflush(E->fp);
	exit(1);
    }
  
   /* Format for reading the input file  */

    sprintf(input_token," %%d ");
    for(i=2;i<column;i++)
	strcat(input_token," %*s");
    strcat(input_token," %s");

    for(i=1;i<=fnodesx*fnodesz*fnodesy;i++) {
      if(fgets(discard,4999,fp)==NULL) /* EOF encountered */
	return(2);
      sscanf(discard,input_token,&j,instring); 

      if(j<1 || j > E->mesh.nno)
	fprintf(stderr,"Illegal node value in %s bc file line %d: %d\n",name,i+4,j);
	
      if(strcmp(instring,"U")!=0)  { /* This field is not unconstrained (U) at this node */
	sscanf(instring,"%lf",&value);
	/*fprintf(stderr,"Found %s bc at node %d value %g - %s,%s\n",name,j,value,instring,discard); */
	field[j] = (standard_precision) value;
	flags[j] = flags[j] | ON;
	flags[j] = flags[j] & (~OFF);
      }
    }
    fclose(fp); 
    free((void *)filename);
    free((void *)input_token);
    return(1);
}