Esempio n. 1
0
    def trouverChemin(self, x1, y1, x2, y2, _listePointInteret):
        collisionEntre = self.collider.collisionEntre  #local var perf optim
        startElements = self.pointContenuListe(x1, y1, _listePointInteret)
        endElements = self.pointContenuListe(x2, y2, _listePointInteret)
        blockingElements = startElements + list(
            set(endElements) - set(startElements))  #merge removing duplicates
        t = time.time()
        #self.computeElementsCollisonList(_listePointInteret)
        #print "Init Collisions: " + str(time.time() - t)

        listePointInteret = sorted(
            _listePointInteret,
            key=lambda pointInteret: Ligne("", x1, y1, x1, y1).distanceAvec(
                pointInteret.forme))
        self.resetCollisonLists(listePointInteret)
        #self.fenetre = None
        initLine = Ligne("", x1, y1, x2, y2)
        if self.fenetre:
            initLine.setCouleur("violet")
            initLine.dessiner(self.fenetre)
        pathList = [[initLine]]
        countTest = 0
        tl = time.time()
        while len(pathList) > 0:
            #print("{} loop: {}".format(time.time()-tl, countTest))
            tl = time.time()
            countTest += 1
            #print(pathList)
            path = pathList.pop(0)  #get firt path
            if self.fenetre:
                #self.fenetre.clear()
                for l in path:
                    l.setCouleur("blue")
                    l.dessiner(self.fenetre)
                self.fenetre.win.redraw()
                #time.sleep(0.02)
            ligne = path.pop()  #get last line
            collidePoint = self.enCollisionCarte(ligne, listePointInteret,
                                                 False)
            if not collidePoint:
                path.append(ligne)
                #print countTest
                t = time.time()
                self.simplifierChemin(path, listePointInteret,
                                      blockingElements)
                #print "\tSimplifyPathTime: " + str(time.time() - t)
                #print "Chemin Simplified len ", len(path)
                return path
            else:
                collidedObjects = [collidePoint]
                self.computeCollisonList(collidePoint, listePointInteret)
                collidedObjects += collidePoint.collisionList
                #find objects coliding current object
                """for obj in listePointInteret:
                    if obj == collidePoint:
                        continue
                    formeCollidePoint = collidePoint.zoneEvitement.forme if collidePoint.zoneEvitement else collidePoint.forme
                    formeObj = obj.zoneEvitement.forme if obj.zoneEvitement else obj.forme
                    if self.collider.collisionEntre(formeCollidePoint, formeObj):
                        collidedObjects.append(obj)"""

                points = []
                for collidedObj in collidedObjects:
                    #List collided object's points
                    objectPoints = []
                    forme = collidedObj.zoneEvitement.forme if collidedObj.zoneEvitement else collidedObj.forme
                    #print("colided with {} {}".format(forme.__class__.__name__, collidedObj.nom ))
                    if isinstance(forme, Ligne):
                        objectPoints.append(
                            self.extendLinePoint(forme, forme.x1, forme.y1))
                        objectPoints.append(
                            self.extendLinePoint(forme, forme.x2, forme.y2))
                    if isinstance(forme, Rectangle):
                        objectPoints.append(
                            self.extendLinePoint(forme, forme.x1, forme.y1))
                        objectPoints.append(
                            self.extendLinePoint(forme, forme.x2, forme.y1))
                        objectPoints.append(
                            self.extendLinePoint(forme, forme.x1, forme.y2))
                        objectPoints.append(
                            self.extendLinePoint(forme, forme.x2, forme.y2))
                    if isinstance(forme, Polygone):
                        for p in forme.pointList:
                            objectPoints.append(
                                self.extendLinePoint(forme, p["x"], p["y"]))
                    if isinstance(forme, Cercle):
                        nbpoint = 8
                        for i in numpy.arange(0, math.pi * 2,
                                              math.pi * 2 / (nbpoint + 1)):
                            x = forme.x + forme.rayon * 1. * math.sin(i)
                            y = forme.y + forme.rayon * 1. * math.cos(i)
                            objectPoints.append(
                                self.extendLinePoint(forme, x, y))
                            """c = Cercle("", x, y, 10, "white")
                            c.dessiner(self.fenetre)
                            self.fenetre.win.redraw()"""

                    #Exclude points colliding with direct line
                    for p in objectPoints:
                        #Exclude out of table
                        if p["x"] < 0 or p["x"] > self.largeur or p[
                                "y"] < 0 or p["y"] > self.longueur:
                            continue
                        #Exclude same point
                        if ligne.x1 == p["x"] and ligne.y1 == p["y"]:
                            continue
                        #Exclude point already in path
                        found = False
                        for l in path:
                            if (l.x1 == p["x"] and l.y1 == p["y"]) or (
                                    l.x2 == p["x"] and l.y2 == p["y"]):
                                found = True
                                break
                        if found:
                            continue
                        #Exculde from collisions
                        directLine = Ligne("", ligne.x1, ligne.y1, p["x"],
                                           p["y"])
                        if collisionEntre(directLine, forme):
                            continue
                        if self.enCollisionCarte(directLine, listePointInteret,
                                                 False):
                            continue
                        if self.fenetre:
                            c = Cercle("", p["x"], p["y"], 10, "black")
                            c.dessiner(self.fenetre)
                            self.fenetre.win.redraw()
                        points.append(p)

                for p in points:
                    """c = Cercle("", p["x"], p["y"], 10, "orange")
                    c.dessiner(self.fenetre)
                    self.fenetre.win.redraw()"""
                    newPath = list(path)
                    newPath.append(
                        Ligne("", ligne.x1, ligne.y1, p["x"], p["y"]))
                    newPath.append(
                        Ligne("", p["x"], p["y"], ligne.x2, ligne.y2))
                    pathList.append(newPath)
                #Explore Paths with points
                #print("points: {}".format(len(points)))

                #Remove path ending at same point
                pai = 0
                while pai < len(pathList):
                    pa = pathList[pai]
                    #Look if other path reach same line
                    pa_length = 0
                    stop = False
                    lai = 0
                    while lai < len(pa) - 1:
                        la = pa[lai]
                        pa_length += la.getlongeur()
                        #look for same line in other path
                        pbi = 0
                        while pbi < len(pathList):
                            if pai == pbi:
                                pbi += 1
                                continue
                            pb = pathList[pbi]
                            pb_length = 0
                            lbi = 0
                            while lbi < len(pb) - 1:
                                lb = pb[lbi]
                                pb_length += lb.getlongeur()
                                if la.x1 == lb.x1 and la.y1 == lb.y1 and la.x2 == lb.x2 and la.y2 == lb.y2:
                                    if pa_length < pb_length:
                                        pbi -= 1
                                        pathList.pop(pbi)
                                        break
                                    else:
                                        pathList.pop(pai)
                                        pai -= 1
                                        stop = True
                                        break
                                lbi += 1
                            if stop:
                                break
                            pbi += 1
                        lai += 1
                        if stop:
                            break
                    pai += 1

                shortestPathMap = {}
                conservedPath = []
                """for currentPath in pathList:
                    length = 0
                    endLine = None
                    for l in range(1, len(currentPath)):
                        if l == len(currentPath)-1:
                            endLine = currentPath[l]
                        else:
                            length += currentPath[l].getlongeur()
                    if not endLine:
                        conservedPath.append(currentPath)
                        continue
                    x = endLine.x1
                    y = endLine.y1
                    key = str(x)+","+str(y)
                    if (key in shortestPathMap and shortestPathMap[key]["length"] > length) or not key in shortestPathMap:
                        shortestPathMap[key] = {"length": length, "path": currentPath}
                for key, noeud in shortestPathMap.iteritems():
                    conservedPath.append(noeud["path"])
                pathList = conservedPath"""

        return []
        """
    def trouverChemin(self, x1, y1, x2, y2, _listePointInteret):
        self.graph.nettoyer()
        #Point contained in objects
        startElements = self.pointContenuListe(x1, y1, _listePointInteret)
        endElements = self.pointContenuListe(x2, y2, _listePointInteret)
        blockingElements = startElements + list(
            set(endElements) - set(startElements))  #merge removing duplicates

        notBlockingElements = list(
            set(_listePointInteret) - set(blockingElements))
        directLine = Ligne("", x1, y1, x2, y2)
        if not self.enCollisionCarte(directLine, notBlockingElements):
            return [directLine]
        elif self.fenetre:
            directLine.setCouleur("violet")
            directLine.dessiner(self.fenetre)

        startNode = self.graph.trouverPointProche(x1, y1)
        endNode = self.graph.trouverPointProche(x2, y2)
        if startNode == None or endNode == None:
            print "Start or end node not found"
            return None
        listnoeud = deque()
        listnoeud.append(startNode)
        self.graph.marquer(startNode)

        while len(listnoeud) > 0:
            currentNode = listnoeud.popleft()
            if currentNode == endNode:
                break
            for noeud in self.graph.getVoisin(currentNode):
                if not self.graph.estMaquer(noeud):
                    addNode = True
                    if len(noeud.colisionObject) != 0:
                        for elem in noeud.colisionObject:
                            if not elem in blockingElements:
                                self.graph.marquer(noeud)
                                addNode = False
                                break
                    if (addNode):
                        self.graph.setPere(noeud, currentNode)
                        self.graph.marquer(noeud)
                        listnoeud.append(noeud)

        listPoint = []
        lastNode = endNode
        currentNode = self.graph.getPere(endNode)
        if currentNode == None:
            pass
        elif self.graph.getPere(currentNode) == None:
            #from endNode
            listPoint.append([x2, y2])
            #trip
            listPoint.append([lastNode.x, lastNode.y])
            listPoint.append([currentNode.x, currentNode.y])
            #to startNode
            listPoint.append([x1, y1])
        else:
            #from endNode
            listPoint.append([x2, y2])
            listPoint.append([lastNode.x, lastNode.y])
            #trip
            while self.graph.getPere(currentNode) != None:
                listPoint.append([currentNode.x, currentNode.y])
                currentNode = self.graph.getPere(currentNode)
            # to startNode
            listPoint.append([x1, y1])

        tmpList = list(_listePointInteret)

        for elem in blockingElements:
            try:
                tmpList.remove(elem)
            except ValueError:
                print "ChercheurChemin Err:" + elem.nom  #shouldn't pop anymore

        listPoint.reverse()
        listChemin = []
        for i in range(1, len(listPoint)):
            p1 = listPoint[i - 1]
            p2 = listPoint[i]
            line = Ligne("", p1[0], p1[1], p2[0], p2[1])
            listChemin.append(line)
        print "Chemin len ", len(listChemin)
        self.simplifierChemin(listChemin, tmpList)
        print "Chemin Simplified len ", len(listChemin)

        return listChemin