Esempio n. 1
0
File: pia.c Progetto: jjgreen/pia
extern float pia_area(const point_t *a, size_t na,
		      const point_t *b, size_t nb)
{
  if ( (na < 3) || (nb < 3) ) return 0.0;

  box_t B = {{ FLT_MAX,  FLT_MAX},
	     {-FLT_MAX, -FLT_MAX}};

  range(a, na, &B);
  range(b, nb, &B);

  const float
    gamut = 500000000.0,
    mid   = gamut / 2.0;
  float
    rngx = B.max.x - B.min.x,
    sclx = gamut / rngx,
    rngy = B.max.y - B.min.y,
    scly = gamut / rngy;
  vertex_t ipa[na + 1], ipb[nb + 1];

  fit(a, na, ipa, 0, sclx, scly, mid, B);
  fit(b, nb, ipb, 2, sclx, scly, mid, B);

  double ascale = (double)sclx * (double)scly;
  int64_t s = 0;

  for (size_t j = 0 ; j < na ; ++j)
    {
      for (size_t k = 0 ; k < nb ; ++k)
	{
	  if ( ovl(ipa[j].rx, ipb[k].rx) && ovl(ipa[j].ry, ipb[k].ry) )
	    {
	      int64_t
		a1 = -area(ipa[j].ip, ipb[k].ip, ipb[k + 1].ip),
		a2 =  area(ipa[j + 1].ip, ipb[k].ip, ipb[k + 1].ip);

	      bool o = (a1<0);

	      if (o == (a2<0))
		{
		  int64_t
		    a3 = area(ipb[k].ip, ipa[j].ip, ipa[j + 1].ip),
		    a4 = -area(ipb[k + 1].ip, ipa[j].ip, ipa[j + 1].ip);

		  if ((a3<0) == (a4<0))
		    {
		      if (o)
			cross(ipa + j, ipa + j + 1, ipb + k, ipb + k + 1, a1, a2, a3, a4, &s);
		      else
			cross(ipb + k, ipb + k + 1, ipa + j, ipa + j + 1, a3, a4, a1, a2, &s);
		    }
		}
	    }
	}
    }

  inness(ipa, na, ipb, nb, &s);
  inness(ipb, nb, ipa, na, &s);

  return s / ascale;
}
Esempio n. 2
0
double DkIntersectPoly::compute() {

	// defines
	gamut = 500000000;
	minRange = nmc::DkVector(FLT_MAX, FLT_MAX);
	maxRange = nmc::DkVector(-FLT_MAX, -FLT_MAX);
	computeBoundingBox(vecA, &minRange, &maxRange);
	computeBoundingBox(vecB, &minRange, &maxRange);

	scale = maxRange - minRange;

	if (scale.minCoord() == 0) return 0; //rechteck mit h�he oder breite = 0

	scale.x = gamut / scale.x;
	scale.y = gamut / scale.y;

	float ascale = scale.x * scale.y;

	// check input
	if (vecA.size() < 3 || vecB.size() < 3) {
		qDebug() << "The polygons must consist of at least 3 points but they are: (vecA: " << vecA.size() << ", vecB: " << vecB.size();
		return 0;
	}

	// compute edges
	std::vector<DkVertex> ipA;
	std::vector<DkVertex> ipB;

	getVertices(vecA, &ipA, 0);
	getVertices(vecB, &ipB, 2);

	for (unsigned int idxA = 0; idxA < ipA.size() - 1; idxA++) {
		for (unsigned int idxB = 0; idxB < ipB.size() - 1; idxB++) {

			if (ovl(ipA[idxA].rx, ipB[idxB].rx) && ovl(ipA[idxA].ry, ipB[idxB].ry)) {

				int64 a1 = -area(ipA[idxA].ip, ipB[idxB].ip, ipB[idxB + 1].ip);
				int64 a2 = area(ipA[idxA + 1].ip, ipB[idxB].ip, ipB[idxB + 1].ip);

				if (a1 < 0 == a2 < 0) {
					int64 a3 = area(ipB[idxB].ip, ipA[idxA].ip, ipA[idxA + 1].ip);
					int64 a4 = -area(ipB[idxB + 1].ip, ipA[idxA].ip, ipA[idxA + 1].ip);

					if (a3 < 0 == a4 < 0) {

						if (a1 < 0) {
							cross(ipA[idxA], ipA[idxA + 1], ipB[idxB], ipB[idxB + 1], (double)a1, (double)a2, (double)a3, (double)a4);
							ipA[idxA].in++;
							ipB[idxB].in--;
						}
						else {
							cross(ipB[idxB], ipB[idxB + 1], ipA[idxA], ipA[idxA + 1], (double)a3, (double)a4, (double)a1, (double)a2);
							ipA[idxA].in--;
							ipB[idxB].in++;
						}
					}
				}

			}
		}
	}

	inness(ipA, ipB);
	inness(ipB, ipA);

	double areaD = (double)interArea / (ascale + FLT_MIN);

	return areaD;

}