Beispiel #1
0
int UpdateInteriorFlag(Vec *p, int interiorFlag, 
                       int pEndpointFromQdir, int qEndpointFromPdir)
{
   double lon, lat;

   if(debug >= 4)
   {
      lon = atan2(p->y, p->x)/dtr;
      lat = asin(p->z)/dtr;

      printf("   intersection [%13.6e,%13.6e,%13.6e]  -> (%10.6f,%10.6f) (UpdateInteriorFlag)\n",
         p->x, p->y, p->z, lon, lat);
      fflush(stdout);
   }

   SaveVertex(p);


   /* Update interiorFlag. */

   if(pEndpointFromQdir == COUNTERCLOCKWISE)
      return P_IN_Q;

   else if(qEndpointFromPdir == COUNTERCLOCKWISE)
      return Q_IN_P;

   else /* Keep status quo. */
      return interiorFlag;
}
Beispiel #2
0
void SaveSharedSeg(Vec *p, Vec *q)
{
   if(debug >= 4)
   {
      printf("\n   SaveSharedSeg():  from [%13.6e,%13.6e,%13.6e]\n",
         p->x, p->y, p->z);

      printf("   SaveSharedSeg():  to   [%13.6e,%13.6e,%13.6e]\n\n",
         q->x, q->y, q->z);

      fflush(stdout);
   }

   SaveVertex(p);
   SaveVertex(q);
}
Beispiel #3
0
/*
 * Print out the second point of intersection and toggle in/out flag.
 */
int UpdateInteriorFlag(Vec *p, int interiorFlag, int pEndpointFromQdir,
                       int qEndpointFromPdir) {
  double lon, lat;

  if (DEBUG >= 4) {
    lon = atan2(p->y, p->x) / DEG_TO_RADIANS;
    lat = asin(p->z) / DEG_TO_RADIANS;

    printf("   intersection [%13.6e,%13.6e,%13.6e]  "
           "-> (%10.6f,%10.6f) (UpdateInteriorFlag)\n",
           p->x, p->y, p->z, lon, lat);
    fflush(stdout);
  }

  SaveVertex(p);

  // Update interiorFlag.

  if (pEndpointFromQdir == COUNTERCLOCKWISE)
    return P_IN_Q;

  else if (qEndpointFromPdir == COUNTERCLOCKWISE)
    return Q_IN_P;

  else
    // Keep status quo.
    return interiorFlag;
}
Beispiel #4
0
/*
 * Sets up the polygons, runs the overlap computation, and returns the area of overlap.
 */
double computeOverlap(double *ilon, double *ilat, double *olon, double *olat,
                      int energyMode, double refArea, double *areaRatio) {
  int i;
  double thisPixelArea;

  *areaRatio = 1.;

  if (energyMode) {
    nv = 0;

    for (i = 0; i < 4; ++i)
      SaveVertex(&P[i]);

    thisPixelArea = Girard();

    *areaRatio = thisPixelArea / refArea;
  }

  nv = 0;

  if (DEBUG >= 4) {
    printf("Input (P):\n");
    for (i = 0; i < 4; ++i)
      printf("%10.6f %10.6f\n", ilon[i], ilat[i]);

    printf("\nOutput (Q):\n");
    for (i = 0; i < 4; ++i)
      printf("%10.6f %10.6f\n", olon[i], olat[i]);

    printf("\n");
    fflush(stdout);
  }

  for (i = 0; i < 4; ++i) {
    P[i].x = cos(ilon[i]) * cos(ilat[i]);
    P[i].y = sin(ilon[i]) * cos(ilat[i]);
    P[i].z = sin(ilat[i]);
  }

  for (i = 0; i < 4; ++i) {
    Q[i].x = cos(olon[i]) * cos(olat[i]);
    Q[i].y = sin(olon[i]) * cos(olat[i]);
    Q[i].z = sin(olat[i]);
  }

  ComputeIntersection(P, Q);

  return (Girard());
}
Beispiel #5
0
/*
 * Advances and prints out an inside vertex if appropriate.
 */
int Advance(int ip, int *p_advances, int n, int inside, Vec *v) {
  double lon, lat;

  lon = atan2(v->y, v->x) / DEG_TO_RADIANS;
  lat = asin(v->z) / DEG_TO_RADIANS;

  if (inside) {
    if (DEBUG >= 4) {
      printf("   Advance(): inside vertex "
             "[%13.6e,%13.6e,%13.6e] -> (%10.6f,%10.6f)n",
             v->x, v->y, v->z, lon, lat);

      fflush(stdout);
    }

    SaveVertex(v);
  }

  (*p_advances)++;

  return (ip + 1) % n;
}
Beispiel #6
0
void  ComputeIntersection(Vec *P, Vec *Q)
{
   Vec  Pdir, Qdir;             /* "Current" directed edges on P and Q   */
   Vec  other;                  /* Temporary "edge-like" variable        */
   int  ip, iq;                 /* Indices of ends of Pdir, Qdir         */
   int  ip_begin, iq_begin;     /* Indices of beginning of Pdir, Qdir    */
   int  PToQDir;                /* Qdir direction relative to Pdir       */
                                /* (e.g. CLOCKWISE)                      */
   int  qEndpointFromPdir;      /* End P vertex as viewed from beginning */
                                /* of Qdir relative to Qdir              */
   int  pEndpointFromQdir;      /* End Q vertex as viewed from beginning */
                                /* of Pdir relative to Pdir              */
   Vec  firstIntersection;      /* Point of intersection of Pdir, Qdir   */
   Vec  secondIntersection;     /* Second point of intersection          */
                                /* (if there is one)                     */
   int  interiorFlag;           /* Which polygon is inside the other     */
   int  contained;              /* Used for "completely contained" check */
   int  p_advances, q_advances; /* Number of times we've advanced        */
                                /* P and Q indices                       */
   int  isFirstPoint;           /* Is this the first point?              */
   int  intersectionCode;       /* SegSegIntersect() return code.        */ 


   /* Check for Q contained in P */

   contained = TRUE;

   for(ip=0; ip<np; ++ip)
   {
      ip_begin = (ip + np - 1) % np;

      Cross(&P[ip_begin], &P[ip], &Pdir);
      Normalize(&Pdir);

      for(iq=0; iq<nq; ++iq)
      {
	 if(debug >= 4)
	 {
	    printf("Q in P: Dot%d%d = %12.5e\n", ip, iq, Dot(&Pdir, &Q[iq]));
	    fflush(stdout);
	 }

	 if(Dot(&Pdir, &Q[iq]) < -tolerance)
	 {
	    contained = FALSE;
	    break;
	 }
      }

      if(!contained)
	 break;
   }

   if(contained)
   {
      if(debug >= 4)
      {
	 printf("Q is entirely contained in P (output pixel is in input pixel)\n");
	 fflush(stdout);
      }

      for(iq=0; iq<nq; ++iq)
	 SaveVertex(&Q[iq]);
      
      return;
   }


   /* Check for P contained in Q */

   contained = TRUE;

   for(iq=0; iq<nq; ++iq)
   {
      iq_begin = (iq + nq - 1) % nq;

      Cross(&Q[iq_begin], &Q[iq], &Qdir);
      Normalize(&Qdir);

      for(ip=0; ip<np; ++ip)
      {
	 if(debug >= 4)
	 {
	    printf("P in Q: Dot%d%d = %12.5e\n", iq, ip, Dot(&Qdir, &P[ip]));
	    fflush(stdout);
	 }

	 if(Dot(&Qdir, &P[ip]) < -tolerance)
	 {
	    contained = FALSE;
	    break;
	 }
      }

      if(!contained)
	 break;
   }

   if(contained)
   {
      if(debug >= 4)
      {
	 printf("P is entirely contained in Q (input pixel is in output pixel)\n");
	 fflush(stdout);
      }

      nv = 0;
      for(ip=0; ip<np; ++ip)
	 SaveVertex(&P[ip]);
      
      return;
   }


   /* Then check for polygon overlap */

   ip = 0;
   iq = 0;

   p_advances = 0;
   q_advances = 0;

   interiorFlag = UNKNOWN;
   isFirstPoint = TRUE;

   while(FOREVER)
   {
      if(p_advances >= 2*np) break;
      if(q_advances >= 2*nq) break;
      if(p_advances >= np && q_advances >= nq) break;

      if(debug >= 4)
      {
         printf("-----\n");

	 if(interiorFlag == UNKNOWN)
	 {
	    printf("Before advances (UNKNOWN interiorFlag): ip=%d, iq=%d ", ip, iq);
	    printf("(p_advances=%d, q_advances=%d)\n", 
	       p_advances, q_advances);
	 }

	 else if(interiorFlag == P_IN_Q)
	 {
	    printf("Before advances (P_IN_Q): ip=%d, iq=%d ", ip, iq);
	    printf("(p_advances=%d, q_advances=%d)\n", 
	       p_advances, q_advances);
	 }

	 else if(interiorFlag == Q_IN_P)
	 {
	    printf("Before advances (Q_IN_P): ip=%d, iq=%d ", ip, iq);
	    printf("(p_advances=%d, q_advances=%d)\n", 
	       p_advances, q_advances);
	 }
	 else
	    printf("\nBAD INTERIOR FLAG.  Shouldn't get here\n");
            
	 fflush(stdout);
      }


      /* Previous point in the polygon */

      ip_begin = (ip + np - 1) % np;
      iq_begin = (iq + nq - 1) % nq;


      /* The current polygon edges are given by  */
      /* the cross product of the vertex vectors */

      Cross(&P[ip_begin], &P[ip], &Pdir);
      Cross(&Q[iq_begin], &Q[iq], &Qdir);

      PToQDir = DirectionCalculator(&P[ip], &Pdir, &Qdir);

      Cross(&Q[iq_begin], &P[ip], &other);
      pEndpointFromQdir = DirectionCalculator(&Q[iq_begin], &Qdir, &other);

      Cross(&P[ip_begin], &Q[iq], &other);
      qEndpointFromPdir = DirectionCalculator(&P[ip_begin], &Pdir, &other);

      if(debug >= 4)
      {
         printf("   ");
	 printDir("P", "Q", PToQDir);
	 printDir("pEndpoint", "Q", pEndpointFromQdir);
	 printDir("qEndpoint", "P", qEndpointFromPdir);
         printf("\n");
	 fflush(stdout);
      }


      /* Find point(s) of intersection between edges */

      intersectionCode = SegSegIntersect(&Pdir,      &Qdir, 
                                         &P[ip_begin], &P[ip],
                                         &Q[iq_begin], &Q[iq], 
                                         &firstIntersection, 
                                         &secondIntersection);

      if(intersectionCode == NORMAL_INTERSECT 
      || intersectionCode == ENDPOINT_ONLY) 
      {
         if(interiorFlag == UNKNOWN && isFirstPoint) 
         {
            p_advances = 0;
            q_advances = 0;

            isFirstPoint = FALSE;
         }

         interiorFlag = UpdateInteriorFlag(&firstIntersection, interiorFlag, 
                                           pEndpointFromQdir, qEndpointFromPdir);

         if(debug >= 4)
	 {
	    if(interiorFlag == UNKNOWN)
	       printf("   interiorFlag -> UNKNOWN\n");

	    else if(interiorFlag == P_IN_Q)
	       printf("   interiorFlag -> P_IN_Q\n");

	    else if(interiorFlag == Q_IN_P)
	       printf("   interiorFlag -> Q_IN_P\n");

	    else 
	       printf("   BAD interiorFlag.  Shouldn't get here\n");

	    fflush(stdout);
	 }
      }


      /*-----Advance rules-----*/


      /* Special case: Pdir & Qdir overlap and oppositely oriented. */

      if((intersectionCode == COLINEAR_SEGMENTS)
      && (Dot(&Pdir, &Qdir) < 0))
      {
         if(debug >= 4)
	 {
            printf("   ADVANCE: Pdir and Qdir are colinear.\n");
	    fflush(stdout);
	 }

         SaveSharedSeg(&firstIntersection, &secondIntersection);

	 RemoveDups();
	 return;
      }


      /* Special case: Pdir & Qdir parallel and separated. */
      
      if((PToQDir          == PARALLEL) 
      && (pEndpointFromQdir == CLOCKWISE) 
      && (qEndpointFromPdir == CLOCKWISE))
      {
         if(debug >= 4)
	 {
            printf("   ADVANCE: Pdir and Qdir are disjoint.\n");
	    fflush(stdout);
	 }

	 RemoveDups();
	 return;
      }


      /* Special case: Pdir & Qdir colinear. */

      else if((PToQDir          == PARALLEL) 
           && (pEndpointFromQdir == PARALLEL) 
           && (qEndpointFromPdir == PARALLEL)) 
      {
         if(debug >= 4)
	 {
            printf("   ADVANCE: Pdir and Qdir are colinear.\n");
	    fflush(stdout);
	 }


         /* Advance but do not output point. */

         if(interiorFlag == P_IN_Q)
            iq = Advance(iq, &q_advances, nq, interiorFlag == Q_IN_P, &Q[iq]);
         else
            ip = Advance(ip, &p_advances, np, interiorFlag == P_IN_Q, &P[ip]);
      }


      /* Generic cases. */

      else if(PToQDir == COUNTERCLOCKWISE 
	   || PToQDir == PARALLEL)
      {
         if(qEndpointFromPdir == COUNTERCLOCKWISE)
         {
            if(debug >= 4)
	    {
               printf("   ADVANCE: Generic: PToQDir is COUNTERCLOCKWISE ");
	       printf("|| PToQDir is PARALLEL, ");
	       printf("qEndpointFromPdir is COUNTERCLOCKWISE\n");
	       fflush(stdout);
	    }

            ip = Advance(ip, &p_advances, np, interiorFlag == P_IN_Q, &P[ip]);
         }
         else
         {
            if(debug >= 4)
            {
               printf("   ADVANCE: Generic: PToQDir is COUNTERCLOCKWISE ");
               printf("|| PToQDir is PARALLEL, qEndpointFromPdir is CLOCKWISE\n");
	       fflush(stdout);
            }

            iq = Advance(iq, &q_advances, nq, interiorFlag == Q_IN_P, &Q[iq]);
         }
      }

      else 
      {
         if(pEndpointFromQdir == COUNTERCLOCKWISE)
         {
            if(debug >= 4)
            {
               printf("   ADVANCE: Generic: PToQDir is CLOCKWISE, ");
               printf("pEndpointFromQdir is COUNTERCLOCKWISE\n");
	       fflush(stdout);
            }

            iq = Advance(iq, &q_advances, nq, interiorFlag == Q_IN_P, &Q[iq]);
         }
         else
         {
            if(debug >= 4)
            {
               printf("   ADVANCE: Generic: PToQDir is CLOCKWISE, ");
               printf("pEndpointFromQdir is CLOCKWISE\n");
	       fflush(stdout);
            }

            ip = Advance(ip, &p_advances, np, interiorFlag == P_IN_Q, &P[ip]);
         }
      }

      if(debug >= 4)
      {
	 if(interiorFlag == UNKNOWN)
	 {
	    printf("After  advances: ip=%d, iq=%d ", ip, iq);
	    printf("(p_advances=%d, q_advances=%d) interiorFlag=UNKNOWN\n", 
	       p_advances, q_advances);
	 }

	 else if(interiorFlag == P_IN_Q)
	 {
	    printf("After  advances: ip=%d, iq=%d ", ip, iq);
	    printf("(p_advances=%d, q_advances=%d) interiorFlag=P_IN_Q\n", 
	       p_advances, q_advances);
	 }

	 else if(interiorFlag == Q_IN_P)
	 {
	    printf("After  advances: ip=%d, iq=%d ", ip, iq);
	    printf("(p_advances=%d, q_advances=%d) interiorFlag=Q_IN_P\n", 
	       p_advances, q_advances);
	 }
	 else
	    printf("BAD INTERIOR FLAG.  Shouldn't get here\n");

         printf("-----\n\n");
	 fflush(stdout);
      }
   }


   RemoveDups();
   return;
}
Beispiel #7
0
double computeOverlap(double *ilon, double *ilat,
                      double *olon, double *olat, 
		      int energyMode, double refArea, double *areaRatio)
{
   int    i;
   double thisPixelArea;

   pi  = atan(1.0) * 4.;
   dtr = pi / 180.;


   *areaRatio = 1.;

   if(energyMode)
   {
      nv = 0;

      for(i=0; i<4; ++i)
      SaveVertex(&P[i]);

      thisPixelArea = Girard();

      *areaRatio = thisPixelArea / refArea;
   }


   nv = 0;

   if(debug >= 4)
   {
      printf("\n-----------------------------------------------\n\nAdding pixel (%d,%d) to pixel (%d,%d)\n\n",
         inRow, inColumn, outRow, outColumn);

      printf("Input (P):\n");
      for(i=0; i<4; ++i)
         printf("%10.6f %10.6f\n", ilon[i], ilat[i]);

      printf("\nOutput (Q):\n");
      for(i=0; i<4; ++i)
         printf("%10.6f %10.6f\n", olon[i], olat[i]);

      printf("\n");
      fflush(stdout);
   }

   for(i=0; i<4; ++i)
   {
      P[i].x = cos(ilon[i]*dtr) * cos(ilat[i]*dtr);
      P[i].y = sin(ilon[i]*dtr) * cos(ilat[i]*dtr);
      P[i].z = sin(ilat[i]*dtr);
   }

   for(i=0; i<4; ++i)
   {
      Q[i].x = cos(olon[i]*dtr) * cos(olat[i]*dtr);
      Q[i].y = sin(olon[i]*dtr) * cos(olat[i]*dtr);
      Q[i].z = sin(olat[i]*dtr);
   }

   ComputeIntersection(P, Q);

   return(Girard());
}