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; }
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; }