Esempio n. 1
0
def _pointWithinThreshold(x, y, curve, eps):
    """
    See whether *(x, y)* is within *eps* of *curve*.
    """
    path = QPainterPath()
    path.addEllipse(x - eps, y - eps, 2 * eps, 2 * eps)
    curvePath = QPainterPath()
    if curve[-1].segmentType == "curve":
        p1, p2, p3, p4 = curve
        curvePath.moveTo(p1.x, p1.y)
        curvePath.cubicTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y)
        curvePath.cubicTo(p3.x, p3.y, p2.x, p2.y, p1.x, p1.y)
    else:
        first = curve[0]
        curvePath.moveTo(first.x, first.y)
        # PACK for fontTools
        pts = []
        for pt in curve:
            pts.append((pt.x, pt.y))
        # draw
        for pt1, pt2 in decomposeQuadraticSegment(pts[1:]):
            curvePath.quadTo(*pt1 + pt2)
        for pt1, pt2 in decomposeQuadraticSegment(list(reversed(pts[:-1]))):
            curvePath.quadTo(*pt1 + pt2)
    return path.intersects(curvePath)
Esempio n. 2
0
def _pointWithinThreshold(x, y, curve, eps):
    """
    See whether *(x, y)* is within *eps* of *curve*.
    """
    path = QPainterPath()
    path.addEllipse(x - eps, y - eps, 2 * eps, 2 * eps)
    curvePath = QPainterPath()
    if curve[-1].segmentType == "curve":
        p1, p2, p3, p4 = curve
        curvePath.moveTo(p1.x, p1.y)
        curvePath.cubicTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y)
        curvePath.cubicTo(p3.x, p3.y, p2.x, p2.y, p1.x, p1.y)
    else:
        first = curve[0]
        curvePath.moveTo(first.x, first.y)
        # PACK for fontTools
        pts = []
        for pt in curve:
            pts.append((pt.x, pt.y))
        # draw
        for pt1, pt2 in decomposeQuadraticSegment(pts[1:]):
            curvePath.quadTo(*pt1+pt2)
        for pt1, pt2 in decomposeQuadraticSegment(list(reversed(pts[:-1]))):
            curvePath.quadTo(*pt1+pt2)
    return path.intersects(curvePath)
Esempio n. 3
0
    def intersects_with(self, point1: QPointF, point2: QPointF) -> bool:
        """Determines if the GraphicsEdge intersects with the cutline.

        Args:
            point1 (QPointF): The starting cutline point.
            point2 (QPointF): The ending cutline point.

        Returns:
            bool: True if the cutline intersects, False otherwise.
        """
        cutpath = QPainterPath(point1)
        cutpath.lineTo(point2)
        path = self.calc_path()
        return cutpath.intersects(path)
Esempio n. 4
0
    def chooseMove(self, init_position, sectors, borders=None):
        smax, lrange, hrange = self.findTarget(sectors)

        best_path = None
        #print ("target", target)
        #print (angle)

        steps = 5
        # FIXME se il fantino e` preciso fare uno scan ulteriore
        # intorno a +- 2.5 gradi dal best (da valutare con semaring dovuto al cavallo)
        for anAngle in range(lrange, hrange, steps):
            collisions = 0
            origin = QVector2D(self.pos.x(), self.pos.y())
            min_dist = origin.distanceToPoint(self.target)
            current_best = [min_dist, 0, origin, anAngle]
            #print("Angolo", anAngle, origin)
            path = QPainterPath()
            path.addEllipse(origin.toPoint(), 20, 20)
            dv = QVector2D(math.cos(math.radians(anAngle)), math.sin(math.radians(anAngle)))
            #print ("dV", dv)
            #print ("orig", origin)
            # for it in self.scene().items():
            #     if it.type() == QGraphicsItem.UserType + 2:
            #         if it == self:
            #             continue
            #         print (it.boundingRect())
            #         pen = QPen(Qt.red, 5, Qt.SolidLine)
            #         self.scene().addPath(it.shape(), pen)
            #         if path.intersects(it.shape()):
            #             print("COLLISION ", it.id)
            # return

            iterS = 0
            while iterS <= int(smax):
            #for i in range(int(smax)):
                origin += dv
                #print ("origin", iterS, origin)
                path.moveTo(origin.toPoint())

                for it in self.scene().items():
                    if it.type() == QGraphicsItem.UserType + 2:
                        if it == self:
                            continue
                        if path.intersects(it.mapToScene(it.shape())):
                            collisions += 1
                            #print ("COLLISION ", it.id)
                            r = QVector2D(it.pos.x() - origin.x(), it.pos.y() - origin.y()).normalized()
                            cos_theta = QVector2D.dotProduct(dv, r)
                            dv_mod_squared = (smax - iterS) * 2 * self.FRICTION * cos_theta * cos_theta
                            #print ("before ", iterS, dv_mod_squared)
                            #print (cos_theta, r)
                            dv_coll = cos_theta * r
                            dv -= dv_coll
                            origin += dv
                            iterS += 0.5 * dv_mod_squared / self.FRICTION
                            #print ( "after ", iterS, smax)
                            #print ("new dv ", dv)
                            break

                # FIXME loop solo sui bordi associati al settore
                for ib, b in enumerate(borders):
                    #FIXME riduci velocita in caso di urto
                    #print ("border ", ib)
                    if path.intersects(b.boundingRect()):
                        #print ("Collision ", ib)
                        new_angle = collisionAngle2(b.line, QLineF((origin+22*dv).toPointF(), origin.toPointF()))
                        #print ("NEW ANGLE ", new_angle)
                        dv = QVector2D(math.cos(new_angle), math.sin(new_angle))
                        #cos_theta = abs(math.cos(math.radians(angle)))
                        #print("angle after: ", angle, cos_theta)

                        # simulare perdita di energia nel rimbalzo
                        #print ("intersect with:", ib, path.currentPosition())
                        #cos_theta = QVector2D.dotProduct(b.direction, dv)
                        #print ("angle after: ", math.degrees(math.acos(cos_theta)))
                        #dv -= 2 * dv * cos_theta
                        #dv = dv.normalized()
                        #print ("dv ", dv)
                        origin += dv
                        break
                #print (collisions)
                tmp_dist = origin.distanceToPoint(self.target) #+ collisions * 200
                #print (tmp_dist)
                if tmp_dist < min_dist:
                    min_dist = tmp_dist
                    current_best = [min_dist, iterS, origin, anAngle]
                    #print (current_best)
                iterS += 1

            #current_best[0] += 0.5*origin.distanceToPoint(sectors[self.currentSector+1].guide)
            sect = -1
            for iSector, s in enumerate(sectors):
                if s.isIn(origin.toPointF()):
                    sect = iSector
                    break
            me = [sect, origin.distanceToPoint(sectors[sect+1].guide)]
            overtakes = 0
            for it in self.scene().items():
                if it == self:
                    continue
                if it.type() == QGraphicsItem.UserType + 2:
                    sect = -1
                    for iSector, s in enumerate(sectors):
                        if s.isIn(origin.toPointF()):
                            sect = iSector
                            break
                    if sect < me[0]:
                        overtakes += 1
                    elif sect == me[0]:
                        dist = it.pos.distanceToPoint(sectors[sect+1].guide)
                        if dist > me[1]:
                            overtakes += 1
            # FIXME modulare questo numero in base alla posizione
            # se e` dietro se ne frega delle collisioni
            delta = - collisions * 100
            print (delta)
            if (10 - overtakes) < init_position:
                delta += (init_position - 10 + overtakes) * 20
                print (delta)

            current_best[0] -= delta
            print ("{}".format(self.id), current_best, self.target, origin)
            if best_path is None:
                best_path = current_best
            else:
                if current_best[0] < best_path[0]:
                    best_path = current_best
                elif abs(current_best[0] - best_path[0])/current_best[0] < 0.05:
                    if current_best[1] < best_path[1]:
                        best_path = current_best

        # salva il percorso con minore distanza dalla guida (poi aggiungere la distanza anche dal prossimo punto)
        #                       minore spazio percorso
            #self.scene().addLine(QLineF(self.pos.x(), origin.x(), self.pos.y(), origin.y()))
        #speed = 40
        #direction = -85
        print ("BEST ", best_path)
        speed = math.sqrt(2*best_path[1]*self.FRICTION)
        #print (speed)
        #self.min_dist = best_path[0]
        # FIXME errore casuale gaussiano in base alla precisione
        # del cavallo
        self.initKinematics(best_path[3], speed)