Exemplo n.º 1
0
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);
    }
}