void Voronoi::checkCircle(VParabola *b) { VParabola *lp = VParabola::getLeftParent (b); VParabola *rp = VParabola::getRightParent(b); VParabola *a = VParabola::getLeftChild (lp); VParabola *c = VParabola::getRightChild(rp); if (!a || !c || a->site == c->site) return; VPoint *s = 0; s = getEdgeIntersection(lp->edge, rp->edge); if (s == 0) return; double dx = a->site->x - s->x; double dy = a->site->y - s->y; double d = std::sqrt((dx * dx) + (dy * dy)); if (s->y - d >= ly) { return; } VEvent *e = new VEvent(new VPoint(s->x, s->y - d), false); points.push_back(e->point); b->cEvent = e; e->arch = b; queue.push(e); }
bool getEdgeIntersection(const Edge* e1, const Edge* e2, Point* intersection, float epsilonExtremity) { return getEdgeIntersection(e1->p0.x, e1->p0.y, e1->p1.x, e1->p1.y, e2->p0.x, e2->p0.y, e2->p1.x, e2->p1.y, intersection, epsilonExtremity); }
void intersectEdgesAgainstComplexCells(Grid *g, std::vector<int> *cellsId, std::vector<Shape>* shapes, std::vector<std::vector<Edge>> *newEdges, IntersectionPoints *intersectionPointsEdges) { int cptShape = -1, cptEdge = -1; std::vector<std::vector<Edge>> newEdgesShapes; for (const Shape &shape : *shapes) { cptShape++; newEdges->push_back(std::vector<Edge>()); for (const Edge &edge : shape.listEdges) { cptEdge++; bool insideComplexeCell = false; std::vector<Point> intersectionPoints; for (const int cellId : *cellsId) { Point tlCellPoint = getTopLeftPointFromCellId(g, cellId); const Edge topEdge = Edge { tlCellPoint, tlCellPoint + Point { float(g->resolution), 0 } }; const Edge rightEdge = Edge { tlCellPoint + Point { float(g->resolution), 0 }, tlCellPoint + Point { float(g->resolution), float(g->resolution) } }; const Edge bottomEdge = Edge { tlCellPoint + Point { 0, float(g->resolution) }, tlCellPoint + Point { float(g->resolution), float(g->resolution) } }; const Edge leftEdge = Edge { tlCellPoint, tlCellPoint + Point { 0, float(g->resolution) } }; Point p; bool intersect = getEdgeIntersection(&topEdge, &edge, &p, 0.00); // les points d'intersection rajoutés a la map peuvent p-e foirer // car ils peuvent etre écrasés par d'autre arrete if (intersect) { intersectionPoints.push_back(p); intersectionPointsEdges->emplace(std::make_pair(cellId, 'T'), p); } intersect = getEdgeIntersection(&rightEdge, &edge, &p, 0.00); if (intersect) { intersectionPoints.push_back(p); intersectionPointsEdges->emplace(std::make_pair(cellId, 'R'), p); } intersect = getEdgeIntersection(&bottomEdge, &edge, &p, 0.00); if (intersect) { intersectionPoints.push_back(p); intersectionPointsEdges->emplace(std::make_pair(cellId, 'B'), p); } intersect = getEdgeIntersection(&leftEdge, &edge, &p, 0.00); if (intersect) { intersectionPoints.push_back(p); intersectionPointsEdges->emplace(std::make_pair(cellId, 'L'), p); } if (edge.p0.x >= tlCellPoint.x && edge.p0.x <= (tlCellPoint.x + g->resolution) && edge.p1.x >= tlCellPoint.x && edge.p1.x <= (tlCellPoint.x + g->resolution) && edge.p0.y >= tlCellPoint.y && edge.p0.y <= (tlCellPoint.y + g->resolution) && edge.p1.y >= tlCellPoint.y && edge.p1.y <= (tlCellPoint.y + g->resolution)) { insideComplexeCell = true; } } if (intersectionPoints.size() == 0) { // si l'arrete est a l'exterieure de la cell on l'ajoute if (!insideComplexeCell) newEdges->at(cptShape).push_back(edge); continue; } // nous avons pour cette arrete les differents points ou celle ci est decoupee // il faut trier ceux-ci et enlever les doublons intersectionPoints.push_back(edge.p0); intersectionPoints.push_back(edge.p1); if (edge.p0.x != edge.p1.x) { if (edge.p0.x < edge.p1.x) { std::sort(intersectionPoints.begin(), intersectionPoints.end(), [](Point a, Point b) { return a.x < b.x; }); } else { std::sort(intersectionPoints.begin(), intersectionPoints.end(), [](Point a, Point b) { return a.x > b.x; }); } } else if (edge.p0.y != edge.p1.y) { if (edge.p0.y < edge.p1.y) { std::sort(intersectionPoints.begin(), intersectionPoints.end(), [](Point a, Point b) { return a.y < b.y; }); } else { std::sort(intersectionPoints.begin(), intersectionPoints.end(), [](Point a, Point b) { return a.y > b.y; }); } } else { std::cout << "no sort"; } // suppression des doublons intersectionPoints.erase(std::unique(intersectionPoints.begin(), intersectionPoints.end()), intersectionPoints.end()); int nbNewEdges = intersectionPoints.size() - 1; for (int i = 0; i < nbNewEdges; i++) { newEdges->at(cptShape).push_back({intersectionPoints[i], intersectionPoints[i+1]}); } } // drawVectorEdges(&newEdges->at(cptShape), window); } }
void detectComplexEdges(Grid* g, std::vector<Shape>* shapes, std::vector<Edge>* complexEdges) { // get edges with intersections EdgesList intersections; for (const Shape &shape : *shapes) { for (const Edge &edge : shape.listEdges) { // bounding box du l'arrete int minX = std::floor(std::min(edge.p0.x, edge.p1.x) / g->resolution); int minY = std::floor(std::min(edge.p0.y, edge.p1.y) / g->resolution); int maxX = std::floor(std::max(edge.p0.x, edge.p1.x) / g->resolution); int maxY = std::floor(std::max(edge.p0.y, edge.p1.y) / g->resolution); for (int i = minY; i <= maxY; i++) { for (int j = minX; j <= maxX; j++) { Point p; bool intersect = getEdgeIntersection(j * g->resolution, i * g->resolution, j * g->resolution, (i + 1) * g->resolution, edge.p0.x, edge.p0.y, edge.p1.x, edge.p1.y, &p, 0.00); if (intersect) { int id = i * g->nbPointWidth + j; KeyEdge e1(id, DIRECTION::down); incrementKey(&intersections, e1); } intersect = getEdgeIntersection(j * g->resolution, i * g->resolution, (j + 1) * g->resolution, i * g->resolution, edge.p0.x, edge.p0.y, edge.p1.x, edge.p1.y, &p, 0.00); if (intersect) { int id = i * g->nbPointWidth + j; KeyEdge e1(id, DIRECTION::right); incrementKey(&intersections, e1); } } } } } // keep only complex edges for (const auto &pair : intersections) { if (pair.second < 2) // l'arrete est intersectee une seule fois continue; int idP1 = pair.first.first; Point p1 = Point { float((idP1 % g->nbPointWidth) * g->resolution), float((idP1 / g->nbPointWidth) * g->resolution) }; int idP2 = idP1; if (pair.first.second == DIRECTION::right) idP2++; else idP2 += g->nbPointWidth; Point p2 = Point { float((idP2 % g->nbPointWidth) * g->resolution), float((idP2 / g->nbPointWidth) * g->resolution) }; Edge e = { p1, p2 }; complexEdges->push_back(e); } }