def timerEvent(self): # Don't move too far away. lineToCenter = QLineF(QPointF(0, 0), self.mapFromScene(0, 0)) if lineToCenter.length() > 150: angleToCenter = math.acos(lineToCenter.dx() / lineToCenter.length()) if lineToCenter.dy() < 0: angleToCenter = Mouse.TwoPi - angleToCenter; angleToCenter = Mouse.normalizeAngle((Mouse.Pi - angleToCenter) + Mouse.Pi / 2) if angleToCenter < Mouse.Pi and angleToCenter > Mouse.Pi / 4: # Rotate left. self.angle += [-0.25, 0.25][self.angle < -Mouse.Pi / 2] elif angleToCenter >= Mouse.Pi and angleToCenter < (Mouse.Pi + Mouse.Pi / 2 + Mouse.Pi / 4): # Rotate right. self.angle += [-0.25, 0.25][self.angle < Mouse.Pi / 2] elif math.sin(self.angle) < 0: self.angle += 0.25 elif math.sin(self.angle) > 0: self.angle -= 0.25 # Try not to crash with any other mice. dangerMice = self.scene().items(QPolygonF([self.mapToScene(0, 0), self.mapToScene(-30, -50), self.mapToScene(30, -50)])) for item in dangerMice: if item is self: continue lineToMouse = QLineF(QPointF(0, 0), self.mapFromItem(item, 0, 0)) angleToMouse = math.acos(lineToMouse.dx() / lineToMouse.length()) if lineToMouse.dy() < 0: angleToMouse = Mouse.TwoPi - angleToMouse angleToMouse = Mouse.normalizeAngle((Mouse.Pi - angleToMouse) + Mouse.Pi / 2) if angleToMouse >= 0 and angleToMouse < Mouse.Pi / 2: # Rotate right. self.angle += 0.5 elif angleToMouse <= Mouse.TwoPi and angleToMouse > (Mouse.TwoPi - Mouse.Pi / 2): # Rotate left. self.angle -= 0.5 # Add some random movement. if len(dangerMice) > 1 and (qrand() % 10) == 0: if qrand() % 1: self.angle += (qrand() % 100) / 500.0 else: self.angle -= (qrand() % 100) / 500.0 self.speed += (-50 + qrand() % 100) / 100.0 dx = math.sin(self.angle) * 10 self.mouseEyeDirection = 0.0 if qAbs(dx / 5) < 1 else dx / 5 self.setRotation(self.rotation() + dx) self.setPos(self.mapToParent(0, -(3 + math.sin(self.speed) * 3)))
def adjust(self): if not self._source or not self._dest: return line = QLineF(self.mapFromItem(self._source, 0, 0), self.mapFromItem(self._dest, 0, 0)) length = line.length() self.prepareGeometryChange() min_len = self._source.radius() + self._dest.radius( ) + self._source.pen().widthF() + self._dest.pen().widthF() if length > min_len: offset = QPointF( (line.dx() * (self._source.radius() + self._source.pen().widthF() + 1)) / length, (line.dy() * (self._source.radius() + self._source.pen().widthF() + 1)) / length) self.source_point = line.p1() + offset offset = QPointF( (line.dx() * (self._dest.radius() + self._dest.pen().widthF() + 1)) / length, (line.dy() * (self._dest.radius() + self._dest.pen().widthF() + 1)) / length) self.dest_point = line.p2() - offset else: self.source_point = self.dest_point = line.p1() path = QPainterPath() if self.sourceNode() == self.destNode(): # Draw self-loops self.__is_self_loop = True radius = self._source.radius() path.moveTo( self.source_point.x() - radius - 2 * self._source.pen().widthF(), self.source_point.y()) path.cubicTo( QPointF(self.source_point.x() - 4 * radius, self.source_point.y()), QPointF(self.source_point.x(), self.source_point.y() - 4 * radius), QPointF( self.dest_point.x(), self.dest_point.y() - radius - 2 * self._source.pen().widthF())) else: self.__is_self_loop = False path.moveTo(self.source_point) path.lineTo(self.dest_point) self.setPath(path)
def paint(self, painter, option, widget): """ Customize line adding an arrow head :param QPainter painter: Painter instance of the item :param option: Painter option of the item :param widget: Widget instance """ if not self.source or not self.destination: return line = QLineF(self.source_point, self.destination_point) if qFuzzyCompare(line.length(), 0): return # Draw the line itself color = QColor() color.setHsv(120 - 60 / self.steps_max * self.steps, 180 + 50 / self.steps_max * self.steps, 150 + 80 / self.steps_max * self.steps) if self.highlighted: color.setHsv(0, 0, 0) style = self.line_style painter.setPen(QPen(color, 1, style, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) # Draw the arrows angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = (2.0 * math.pi) - angle # arrow in the middle of the arc hpx = line.p1().x() + (line.dx() / 2.0) hpy = line.p1().y() + (line.dy() / 2.0) head_point = QPointF(hpx, hpy) painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) destination_arrow_p1 = head_point + QPointF( math.sin(angle - math.pi / 3) * self.arrow_size, math.cos(angle - math.pi / 3) * self.arrow_size) destination_arrow_p2 = head_point + QPointF( math.sin(angle - math.pi + math.pi / 3) * self.arrow_size, math.cos(angle - math.pi + math.pi / 3) * self.arrow_size) painter.setBrush(color) painter.drawPolygon(QPolygonF([head_point, destination_arrow_p1, destination_arrow_p2])) if self.metadata["confirmation_text"]: painter.drawText(head_point, self.metadata["confirmation_text"])
def paint(self, painter, option, widget): """ Customize line adding an arrow head :param QPainter painter: Painter instance of the item :param option: Painter option of the item :param widget: Widget instance """ if not self.source or not self.destination: return line = QLineF(self.source_point, self.destination_point) if qFuzzyCompare(line.length(), 0): return # Draw the line itself color = QColor() style = Qt.SolidLine if self.status == ARC_STATUS_STRONG: color.setNamedColor('blue') if self.status == ARC_STATUS_WEAK: color.setNamedColor('salmon') style = Qt.DashLine painter.setPen(QPen(color, 1, style, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) # Draw the arrows angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = (2.0 * math.pi) - angle # arrow in the middle of the arc hpx = line.p1().x() + (line.dx() / 2.0) hpy = line.p1().y() + (line.dy() / 2.0) head_point = QPointF(hpx, hpy) painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) destination_arrow_p1 = head_point + QPointF( math.sin(angle - math.pi / 3) * self.arrow_size, math.cos(angle - math.pi / 3) * self.arrow_size) destination_arrow_p2 = head_point + QPointF( math.sin(angle - math.pi + math.pi / 3) * self.arrow_size, math.cos(angle - math.pi + math.pi / 3) * self.arrow_size) painter.setBrush(color) painter.drawPolygon(QPolygonF([head_point, destination_arrow_p1, destination_arrow_p2])) if self.metadata["confirmation_text"]: painter.drawText(head_point, self.metadata["confirmation_text"])
def paint(self, painter, option, widget): """ Customize line adding an arrow head :param QPainter painter: Painter instance of the item :param option: Painter option of the item :param widget: Widget instance """ if not self.source or not self.destination: return line = QLineF(self.source_point, self.destination_point) if qFuzzyCompare(line.length(), 0): return # Draw the line itself color = QColor() style = Qt.SolidLine if self.status == ARC_STATUS_STRONG: color.setNamedColor('blue') if self.status == ARC_STATUS_WEAK: color.setNamedColor('salmon') style = Qt.DashLine painter.setPen(QPen(color, 1, style, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) # Draw the arrows angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = (2.0 * math.pi) - angle # arrow in the middle of the arc hpx = line.p1().x() + (line.dx() / 2.0) hpy = line.p1().y() + (line.dy() / 2.0) head_point = QPointF(hpx, hpy) painter.setPen(QPen(color, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) destination_arrow_p1 = head_point + QPointF( math.sin(angle - math.pi / 3) * self.arrow_size, math.cos(angle - math.pi / 3) * self.arrow_size) destination_arrow_p2 = head_point + QPointF( math.sin(angle - math.pi + math.pi / 3) * self.arrow_size, math.cos(angle - math.pi + math.pi / 3) * self.arrow_size) painter.setBrush(color) painter.drawPolygon( QPolygonF([head_point, destination_arrow_p1, destination_arrow_p2]))
def paint(self, painter, option, widget): color = Qt.red if self.isSelected() else Qt.black painter.setPen(QPen(color, 2, Qt.SolidLine)) path = QPainterPath(self.startPoint) # start path # iterating over all points of line for i in range(len(self.points) - 1): x1, y1 = self.points[i].x(), self.points[i].y() x2, y2 = self.points[i + 1].x(), self.points[i + 1].y() for point in sorted(self.commonPathsCenters, key=lambda x: x.x() + x.y(), reverse=x2 < x1 or y2 < y1): x, y = point.x(), point.y() if x == x1 == x2: # vertical if min(y1, y2) + 8 <= y < max(y1, y2) - 8: if y2 > y1: path.lineTo(point - QPointF(0, 8)) path.arcTo(QRectF(x - 8, y - 8, 16, 16), 90, -180) path.moveTo(point + QPointF(0, 8)) else: path.lineTo(point + QPointF(0, 8)) path.arcTo(QRectF(x - 8, y - 8, 16, 16), -90, 180) path.moveTo(point - QPointF(0, 8)) elif y == y1 == y2: # horizontal if min(x1, x2) + 8 <= x < max(x1, x2) - 8: if x2 > x1: path.lineTo(point - QPointF(8, 0)) path.arcTo(QRectF(x - 8, y - 8, 16, 16), 180, 180) path.moveTo(point + QPointF(8, 0)) else: path.lineTo(point + QPointF(8, 0)) path.arcTo(QRectF(x - 8, y - 8, 16, 16), 0, -180) path.lineTo(point - QPointF(8, 0)) path.lineTo(self.points[i + 1]) # draw arrow in last segment if i == len(self.points) - 2: arrow_size = 20.0 line = QLineF(self.points[i], self.points[i + 1]) if line.length() < 20: continue angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = (math.pi * 2) - angle arrow_p1 = line.p2() - QPointF(math.sin(angle + math.pi / 2.5) * arrow_size, math.cos(angle + math.pi / 2.5) * arrow_size) arrow_p2 = line.p2() - QPointF(math.sin(angle + math.pi - math.pi / 2.5) * arrow_size, math.cos(angle + math.pi - math.pi / 2.5) * arrow_size) arrowHead = QPolygonF() arrowHead.append(line.p2()) arrowHead.append(arrow_p1) arrowHead.append(arrow_p2) painter.save() painter.setBrush(Qt.black) painter.drawPolygon(arrowHead) painter.restore() painter.drawPath(path) # draw final path
def set_range(self, SCALE_FACTOR): '''It gives the object a QGraphicsPolygonItem to attack at a certain range ''' # create points vector self.range = SCALE_FACTOR points = [ QPointF(1, 0), QPointF(2, 0), QPointF(3, 1), QPointF(3, 2), QPointF(2, 3), QPointF(1, 3), QPointF(0, 2), QPointF(0, 1) ] # scale points points = [p * SCALE_FACTOR for p in points] # create polygon self.polygon = QPolygonF(points) # create QGraphicsPolygonItem self.attack_area = QGraphicsPolygonItem(self.polygon, self) self.attack_area.setPen(QPen(Qt.DotLine)) # move the polygon poly_center = QPointF(1.5 * SCALE_FACTOR, 1.5 * SCALE_FACTOR) poly_center = self.mapToScene(poly_center) minion_center = QPointF(self.x() + self.pixmap().width() / 2, self.y() + self.pixmap().height() / 2) ln = QLineF(poly_center, minion_center) self.attack_area.setPos(self.x() + ln.dx(), self.y() + ln.dy())
def paint(self, painter, option, widget): assert self.fromSquare is not None assert self.toSquare is not None line = QLineF(self.sourcePoint, self.destPoint) assert(line.length() != 0.0) # Draw the arrows if there's enough room. angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = (math.pi*2.0) - angle destArrowP1 = self.destPoint + QPointF( math.sin(angle - math.pi / 3) * self.arrowSize, math.cos(angle - math.pi / 3) * self.arrowSize ) destArrowP2 = self.destPoint + QPointF( math.sin(angle - math.pi + math.pi / 3) * self.arrowSize, math.cos(angle - math.pi + math.pi / 3) * self.arrowSize ) painter.setPen(self.pen) painter.setBrush(self.brush) # arrowhead1 = QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]) arrowhead2 = QPolygonF([line.p2(), destArrowP1, destArrowP2]) painter.drawPolygon(arrowhead2) painter.setPen(self.pen) painter.drawLine(line)
def paint(self, painter, option, widget): if not self.source or not self.dest: return # Draw the line itself. line = QLineF(self.sourcePoint, self.destPoint) if line.length() == 0.0: return painter.setPen(QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) # Draw the arrows if there's enough room. angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = Edge.TwoPi - angle sourceArrowP1 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi / 3) * self.arrowSize, math.cos(angle + Edge.Pi / 3) * self.arrowSize) sourceArrowP2 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize, math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize); destArrowP1 = self.destPoint + QPointF(math.sin(angle - Edge.Pi / 3) * self.arrowSize, math.cos(angle - Edge.Pi / 3) * self.arrowSize) destArrowP2 = self.destPoint + QPointF(math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize, math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize) painter.setBrush(Qt.black) painter.drawPolygon(QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2])) painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
def adjust(self): if not self.source or not self.dest: return line = QLineF( self.mapFromItem(self.source, self.source.getDrawSize() * -0.5, self.source.getDrawSize() * -0.5), self.mapFromItem(self.dest, self.dest.getDrawSize() * -0.5, self.dest.getDrawSize() * -0.5)) length = line.length() self.prepareGeometryChange() if length > self.source.getDrawSize(): edgeOffset = QPointF( (line.dx() * self.source.getDrawSize() / 2) / length, (line.dy() * self.source.getDrawSize() / 2) / length) self.sourcePoint = line.p1() + edgeOffset self.destPoint = line.p2() - edgeOffset else: self.sourcePoint = line.p1() self.destPoint = line.p1()
def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget=None): if not self.source or not self.dest: return line = QLineF(self.source_point, self.dest_point) if line.length() == 0.0: return color = self.get_color() width = SupremeSettings()['edge_width'] if option.state & QStyle.State_Sunken: color, width = Qt.red, 2 painter.setPen(QPen(Qt.black, 2, Qt.DashLine)) painter.drawPolygon(self.getSelectionPolygon()) elif option.state & QStyle.State_MouseOver: color, width = Qt.blue, 2 painter.setPen( QPen(color, width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = math.pi * 2 - angle if self.arrow_size > 0: dest_arrow_p1 = self.dest_point + QPointF( math.sin(angle - math.pi / 3) * self.arrow_size, math.cos(angle - math.pi / 3) * self.arrow_size) dest_arrow_p2 = self.dest_point + QPointF( math.sin(angle - math.pi + math.pi / 3) * self.arrow_size, math.cos(angle - math.pi + math.pi / 3) * self.arrow_size) painter.setBrush(color) painter.drawPolygon( QPolygonF([line.p2(), dest_arrow_p1, dest_arrow_p2])) self.draw_animated_objects()
def route_compas(xd, yd, xa, ya): line = QLineF(xd, yd, xa, ya) angle = atan2(line.dy(), line.dx()) if degrees(angle) <= -90: return round(90 - degrees(angle), 1) else: return round(90 + degrees(angle), 1)
def move(self, item, dest, moveSpeed): walkLine = QLineF(item.getGuidedPos(), dest) if moveSpeed >= 0 and walkLine.length() > moveSpeed: # The item is too far away from it's destination point so we move # it towards it instead. dx = walkLine.dx() dy = walkLine.dy() if abs(dx) > abs(dy): # Walk along x-axis. if dx != 0: d = moveSpeed * dy / abs(dx) if dx > 0: s = moveSpeed else: s = -moveSpeed dest.setX(item.getGuidedPos().x() + s) dest.setY(item.getGuidedPos().y() + d) else: # Walk along y-axis. if dy != 0: d = moveSpeed * dx / abs(dy) if dy > 0: s = moveSpeed else: s = -moveSpeed dest.setX(item.getGuidedPos().x() + d) dest.setY(item.getGuidedPos().y() + s) item.setGuidedPos(dest)
class GuideLine(Guide): def __init__(self, line_or_point, follows=None): super(GuideLine, self).__init__(follows) if isinstance(line_or_point, QLineF): self.line = line_or_point elif follows is not None: self.line = QLineF(self.prevGuide.endPos(), line_or_point) else: self.line = QLineF(QPointF(0, 0), line_or_point) def length(self): return self.line.length() def startPos(self): return QPointF(self.line.p1().x() * self.scaleX, self.line.p1().y() * self.scaleY) def endPos(self): return QPointF(self.line.p2().x() * self.scaleX, self.line.p2().y() * self.scaleY) def guide(self, item, moveSpeed): frame = item.guideFrame - self.startLength endX = (self.line.p1().x() + (frame * self.line.dx() / self.length())) * self.scaleX endY = (self.line.p1().y() + (frame * self.line.dy() / self.length())) * self.scaleY pos = QPointF(endX, endY) self.move(item, pos, moveSpeed)
def __init__(self): super().__init__() # initialize attack range (area) self.attack_area = QGraphicsPolygonItem() self.attack_dest = QPointF(0, 0) self.has_target = False # set the graphics self.setPixmap( QPixmap('./res/imgs/lol_tower.png').scaled(80, 80, Qt.KeepAspectRatio)) # initializes health h = Bar(self) h.set_max_val(250) h.set_current_val(250) self.set_health(h) self.attack = 30 # create points vector points = [ QPointF(1, 0), QPointF(2, 0), QPointF(3, 1), QPointF(3, 2), QPointF(2, 3), QPointF(1, 3), QPointF(0, 2), QPointF(0, 1) ] # scale points SCALE_FACTOR = 100 points = [p * SCALE_FACTOR for p in points] self.range = SCALE_FACTOR # create polygon self.polygon = QPolygonF(points) # create QGraphicsPolygonItem self.attack_area = QGraphicsPolygonItem(self.polygon, self) self.attack_area.setPen(QPen(Qt.DotLine)) # move the polygon poly_center = QPointF(1.5 * SCALE_FACTOR, 1.5 * SCALE_FACTOR) poly_center = self.mapToScene(poly_center) tower_center = QPointF(self.x() + 40, self.y() + 40) ln = QLineF(poly_center, tower_center) self.attack_area.setPos(self.x() + ln.dx(), self.y() + ln.dy()) # connect a timer to acquire target self.damage_timer = QTimer() self.damage_timer.timeout.connect(self.acquire_target) self.damage_timer.start(1000) # allow responding to hover events self.setAcceptHoverEvents(True)
def updatePosition(self, force=False): #if self.toNode() is None and self.fromNode() is None: #if not force: #self.updateArrowHead() #self.updateTextPosition() #return if self.dest() and self.source(): self._updatingPos = True #self.saveTextPosition() self.prepareGeometryChange() if len(self._points) == 2: a = self.source().closestBoundaryPosToItem(self.dest()) b = self.dest().closestBoundaryPosToItem(self.source()) a = self.mapFromItem(self.source(), a) b = self.mapFromItem(self.dest(), b) else: a = self.source().closestBoundaryPosToItem(self._points[1]) b = self.dest().closestBoundaryPosToItem(self._points[-2]) a = self.mapFromItem(self.source(), a) b = self.mapFromItem(self.dest(), b) line = QLineF(a, b) length = line.length() # BUGFIX if abs(length) == 0: line = QLineF(a, QPointF(a.x() + 1, a.y())) length = 1 dx = line.dx() dx /= length if dx > 1: dx = 1 elif dx < -1: dx = -1 angle = acos(dx) size = self.arrowHeadSize() head = self._arrowHead if line.dy() >= 0: angle = pi * 2 - angle p2 = line.p2() u = p2 + QPointF( sin(angle + pi + pi / 3) * size, cos(angle + pi + pi / 3) * size) v = p2 + QPointF( sin(angle - pi / 3) * size, cos(angle - pi / 3) * size) if self.dest() != self.toPoint(): self.toPoint().setPos(line.p2()) if self.source() != self.fromPoint(): self.fromPoint().setPos(line.p1()) self.updateArrowHead() #self.updateTextPosition() self._updatingPos = False else: self.updateArrowHead() self.updateTextPosition()
class Border(QGraphicsItem): #def __init__(self, x, y, width, height, vx, vy): def __init__(self, x1, y1, x2, y2, dir): super(Border, self).__init__() #self.pos = QPointF(x, y) #self.lines = [QLineF(x, y, x + width, y), # QLineF(x, y, x, y + height), # QLineF(x, y + height, x + width, y + height), # QLineF(x + width, y, x + width, y + height)] #self.width = width #self.height = height #self.rect = QRectF(self.pos.x(), self.pos.y(), self.width, self.height) if dir == 1: self.line = QLineF(x1, y1, x2, y2) else: self.line = QLineF(x2, y2, x1, y1) #self.direction = QVector2D(vx, vy) def type(self): return QGraphicsItem.UserType + 1 # def collisionAngle(self, line): # intersects = (None, 0) # for l in self.lines: # r = line.intersects(l) # print (r, l, line) # if r[0] == 1: # tmp = QLineF(line.p1(), r[1]) # if intersects[0] is None or tmp.length() < intersects[1]: # print ("raggio ", tmp, tmp.length()) # corretto # print ("l ", l, tmp.angleTo(l)) # print ("l_perp ", l.normalVector(), tmp.angleTo(l.normalVector())) # intersects = [tmp, tmp.length(), tmp.angleTo(l.normalVector())] # print ("inter ", intersects) # # if intersects[0] is not None: # return intersects[2] # else: # return 0 def boundingRect(self): #return QRectF(self.pos.x(), self.pos.y(), self.width, self.height) return QRectF(self.line.x1(), self.line.y1(), self.line.dx() + 2, self.line.dy() + 2) def paint(self, painter, option, widget): #painter.setRenderHint(QPainter::Antialiasing); #painter.setPen(Qt::black); painter.setPen(QPen(Qt.black, 5, Qt.SolidLine)) painter.setBrush(QBrush(Qt.red, Qt.VerPattern)) painter.drawLine(self.line)
def move_forward(self): # move object if self.should_be_moving: ln = QLineF(self.pos(), self.destination) ln.setLength(self.speed) self.rotate_to_point(self.destination) # avoid collision colliding_items = self.collidingItems() for i in colliding_items: if isinstance(i, StaticGameObject): collision_line = QLineF(self.pos(), i.pos()) collision_line.setLength(30) self.setPos(self.x() - collision_line.dx(), self.y() - collision_line.dy()) # move object forward at current angle self.setPos(self.x() + ln.dx(), self.y() + ln.dy()) self.x_prev = self.pos().x() self.y_prev = self.pos().y()
def findLowerTangent(self, hull1, hull2): p = self.findRightMostPoint(hull1) q = self.findLeftMostPoint(hull2) h1Size = len(hull1) h2Size = len(hull2) tempLine = QLineF(hull1[p%h1Size].p2(),hull2[q%h2Size].p2()) tangentFound = 0 while tangentFound == 0: tangentFound = 1 # LEFT Hull while tempLine.dy()/tempLine.dx() < QLineF(hull1[(p+1)%h1Size].p2(),hull2[q%h2Size].p2()).dy()/QLineF(hull1[(p+1)%h1Size].p2(),hull2[q%h2Size].p2()).dx(): r = p + 1 tempLine = QLineF(hull1[r%h1Size].p2(),hull2[q%h2Size].p2()) p = r tangentFound = 0 # RIGHT hull while tempLine.dy()/tempLine.dx() > QLineF(hull1[p%h1Size].p2(),hull2[(q-1)%h2Size].p2()).dy()/QLineF(hull1[p%h1Size].p2(),hull2[(q-1)%h2Size].p2()).dx(): r = q - 1 tempLine = QLineF(hull1[p%h1Size].p2(),hull2[r%h2Size].p2()) q = r tangentFound = 0 # print("found lower tangent") return tempLine
def draw_train(self, h_painter, train, points, vert_radius, color): h_painter.setBrush(color) edge = self.__graph.get_edge_by_idx(train.line_idx) p1 = points[edge['vert_from']] p2 = points[edge['vert_to']] length = edge['length'] line = QLineF(p1, p2) cx = p1.x() + (train.position / length) * line.dx() cy = p1.y() + (train.position / length) * line.dy() rect = QRectF(cx - vert_radius * 2 / 3, cy - vert_radius * 2 / 3, vert_radius * 4 / 3, vert_radius * 4 / 3) h_painter.setPen(Qt.black) h_painter.drawRect(rect) h_painter.setPen(Qt.white) h_painter.drawText(rect, Qt.AlignCenter, str(train.goods))
def adjust(self): if not self.source or not self.dest: return line = QLineF(self.mapFromItem(self.source, 0, 0), self.mapFromItem(self.dest, 0, 0)) length = line.length() self.prepareGeometryChange() if length > 20: edge_offset = QPointF( (line.dx() * self.source.size.width() / 2) / length, (line.dy() * self.source.size.height() / 2) / length) self.source_point = line.p1() + edge_offset self.dest_point = line.p2() - edge_offset else: self.source_point = self.dest_point = line.p1()
class MyArrow(QGraphicsLineItem): def __init__(self, scene, Source, Dest): super(MyArrow, self).__init__() #设置起点x,y Source_x = Source[0] Source_y = Source[1] #设置终点x,y Dest_x = Dest[0] Dest_y = Dest[1] #绘制连线 self.source = QPointF(Source_x, Source_y) self.dest = QPointF(Dest_x, Dest_y) self.line = QLineF(self.source, self.dest) self.line.setLength(self.line.length() - 20) scene.addItem(self) def prepareGeometryChange(self): self.update() def paint(self, QPainter, QStyleOptionGraphicsItem, QWidget_widget=None): # setPen pen = QPen() pen.setWidth(2) pen.setJoinStyle(Qt.MiterJoin) QPainter.setPen(pen) # setBrush brush = QBrush() brush.setColor(Qt.black) brush.setStyle(Qt.SolidPattern) QPainter.setBrush(brush) #绘制终点箭头 v = self.line.unitVector() v.setLength(10) v.translate(QPointF(self.line.dx(), self.line.dy())) n = v.normalVector() n.setLength(n.length() * 0.5) n2 = n.normalVector().normalVector() p1 = v.p2() p2 = n.p2() p3 = n2.p2() QPainter.drawLine(self.line) QPainter.drawPolygon(p1, p2, p3)
def draw_edges_and_waypoints(self, h_painter, points, vert_radius): h_painter.setBrush(self.vertex_color) for vertex in self.__graph.get_all_vertices(): for adj_vert in self.__graph.get_adj_vertices(vertex): p1 = points[vertex] p2 = points[adj_vert] h_painter.drawLine(p1, p2) edge = self.__graph.get_edge_by_adj_vert(vertex, adj_vert) line = QLineF(p1, p2) for i in range(1, edge['length']): cx = p1.x() + (i / edge['length']) * line.dx() cy = p1.y() + (i / edge['length']) * line.dy() h_painter.drawEllipse(cx - vert_radius / 4, cy - vert_radius / 4, vert_radius / 2, vert_radius / 2)
def ulti(self): scene_items = self.scene().items() for i in scene_items: if (isinstance(i, Minion) or isinstance(i, BigMinion)) and i.team != self.team: this_line = QLineF(self.pos(), i.pos()) if this_line.length() <= 150: this_line.setLength(150) i.setPos(i.x() + this_line.dx(), i.y() + this_line.dy()) elif (i.__class__.__name__ == 'Tower' or i.__class__.__name__ == 'Nexus' or i.__class__.__name__ == 'Inhibitor') and i.team != self.team: this_line = QLineF(self.pos(), i.pos()) if this_line.length() <= 150: i.decrease_health(100) self.ulti_available = False self.ulti_cooldown_timer.start(self.cooldown)
def move(self, point, quat): """Move trackball""" if not self._pressed: return currentTime = QTime.currentTime() msecs = self._lastTime.msecsTo(currentTime) if msecs <= 20: return if self._mode == self.TrackballMode.Planar: delta = QLineF(self._lastPos, point) self._angularVelocity = 180.0 * delta.length() / (math.pi * msecs) self._axis = QVector3D(-delta.dy(), delta.dx(), 0.0).normalized() self._axis = quat.rotatedVector(self._axis) self._rotation = QQuaternion.fromAxisAndAngle(self._axis, 180.0 / math.pi * delta.length()) * self._rotation elif self._mode == self.TrackballMode.Spherical: lastPos3D = QVector3D(self._lastPos.x(), self._lastPos.y(), 0.0) sqrZ = 1.0 - QVector3D.dotProduct(lastPos3D, lastPos3D) if sqrZ > 0: lastPos3D.setZ(math.sqrt(sqrZ)) else: lastPos3D.normalize() currentPos3D = QVector3D(point.x(), point.y(), 0.0) sqrZ = 1.0 - QVector3D.dotProduct(currentPos3D, currentPos3D) if sqrZ > 0: currentPos3D.setZ(math.sqrt(sqrZ)) else: currentPos3D.normalize() self._axis = QVector3D.crossProduct(lastPos3D, currentPos3D) angle = 180.0 / math.pi * math.asin(math.sqrt(QVector3D.dotProduct(self._axis, self._axis))) self._angularVelocity = angle / msecs self._axis.normalize() self._axis = quat.rotatedVector(self._axis) self._rotation = QQuaternion.fromAxisAndAngle(self._axis, angle) * self._rotation self._lastPos = point self._lastTime = currentTime
def paint(self, painter, option, widget=None): """ Public method to paint the item in local coordinates. @param painter reference to the painter object (QPainter) @param option style options (QStyleOptionGraphicsItem) @param widget optional reference to the widget painted on (QWidget) """ if (option.state & QStyle.State_Selected) == \ QStyle.State(QStyle.State_Selected): width = 2 else: width = 1 # draw the line first line = QLineF(self._origin, self._end) painter.setPen( QPen(Qt.black, width, Qt.SolidLine, Qt.FlatCap, Qt.MiterJoin)) painter.drawLine(line) # draw the arrow head arrowAngle = self._type * ArrowheadAngleFactor slope = math.atan2(line.dy(), line.dx()) # Calculate left arrow point arrowSlope = slope + arrowAngle a1 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope), self._end.y() - self._halfLength * math.sin(arrowSlope)) # Calculate right arrow point arrowSlope = slope - arrowAngle a2 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope), self._end.y() - self._halfLength * math.sin(arrowSlope)) if self._filled: painter.setBrush(Qt.black) else: painter.setBrush(Qt.white) polygon = QPolygonF() polygon.append(line.p2()) polygon.append(a1) polygon.append(a2) painter.drawPolygon(polygon)
def adjust(self): if not self.source or not self.dest: return line = QLineF(self.mapFromItem(self.source, 0, 0), self.mapFromItem(self.dest, 0, 0)) length = line.length() self.prepareGeometryChange() if length > 20.0: edgeOffset = QPointF((line.dx() * 10) / length, (line.dy() * 10) / length) self.sourcePoint = line.p1() + edgeOffset self.destPoint = line.p2() - edgeOffset else: self.sourcePoint = line.p1() self.destPoint = line.p1()
def calculate_forces(self): if not self.scene() or self.scene().mouseGrabberItem() is self: self.newPos = self.pos() return # Sum up all forces pushing this item away. xvel = 0.0 yvel = 0.0 for item in self.scene().items(): if not isinstance(item, Node): continue line = QLineF(self.mapFromItem(item, 0, 0), QPointF(0, 0)) dx = line.dx() dy = line.dy() l = 2.0 * (dx * dx + dy * dy) if l > 0: xvel += (dx * 150.0) / l yvel += (dy * 150.0) / l # Now subtract all forces pulling items together. weight = (len(self.edgeList) + 1) * 10.0 for edge in self.edgeList: if edge.source_node() is self: pos = self.mapFromItem(edge.destination_node(), 0, 0) else: pos = self.mapFromItem(edge.source_node(), 0, 0) xvel += pos.x() / weight yvel += pos.y() / weight if qAbs(xvel) < 0.1 and qAbs(yvel) < 0.1: xvel = yvel = 0.0 sceneRect = self.scene().sceneRect() self.newPos = self.pos() + QPointF(xvel, yvel) self.newPos.setX( min(max(self.newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)) self.newPos.setY( min(max(self.newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10))
def paint(self, painter, option, widget): if not self.source or not self.dest: return # Draw the line itself. line = QLineF(self.sourcePoint, self.destPoint) if line.length() == 0.0: return painter.setPen( QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) # Draw the arrows if there's enough room. angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = Edge.TwoPi - angle destArrowP1 = self.destPoint + QPointF( math.sin(angle - Edge.Pi / 3) * self.arrowSize, math.cos(angle - Edge.Pi / 3) * self.arrowSize) destArrowP2 = self.destPoint + QPointF( math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize, math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize) conditionPoint = self.sourcePoint + QPointF( math.sin(angle + Edge.Pi / 3) * self.arrowSize * 2, math.cos(angle + Edge.Pi / 3) * self.arrowSize * 2) textToPrint = self.condition for path in self.source.edges(): if path.destNode( ).name == self.dest.name and path.condition != self.condition: textToPrint += ", %c" % (path.condition) if path.condition > self.condition: return painter.setBrush(Qt.black) painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2])) painter.drawText(conditionPoint, textToPrint)
def adjust(self): if not self._handle1 or not self._handle2: return line = QLineF(self.mapFromItem(self._handle1, 0, 0), self.mapFromItem(self._handle2, 0, 0)) length = line.length() self.prepareGeometryChange() if length > self.width() * 0.9: offset = QPointF((line.dx() * self.width() / 2) / length, (line.dy() * self.width() / 2) / length) p1 = line.p1() + offset p2 = line.p2() - offset else: p1 = p2 = line.p1() path = QPainterPath() path.moveTo(p1) path.lineTo(p2) self.setPath(path)
def angle_arrow(self, path, origin='head'): ''' Compute the two points of the arrow head with the right angle ''' if origin == 'tail': path = path.toReversed() length = path.length() percent = path.percentAtLength(length - 10.0) src = path.pointAtPercent(percent) #path.moveTo(path.pointAtPercent(1)) end_point = path.pointAtPercent(1) #end_point = path.currentPosition() line = QLineF(src, end_point) angle = math.acos(line.dx() / (line.length() or 1)) if line.dy() >= 0: angle = math.pi * 2 - angle arrow_size = 10.0 arrow_p1 = end_point + QPointF( math.sin(angle - math.pi / 3) * arrow_size, math.cos(angle - math.pi / 3) * arrow_size) arrow_p2 = end_point + QPointF( math.sin(angle - math.pi + math.pi / 3) * arrow_size, math.cos(angle - math.pi + math.pi / 3) * arrow_size) return (arrow_p1, arrow_p2)
def __init__(self, parent=None): super().__init__() # bool to check if it is available self.available = False # set store gui self.gui = Store() # set graphics self.setPixmap(QPixmap('./res/imgs/blue_chest.png').scaled(80, 80, Qt.KeepAspectRatio)) # create points vector points = [QPointF(1, 0), QPointF(2, 0), QPointF(3, 1), QPointF(3, 2), QPointF(2, 3), QPointF(1, 3), QPointF(0, 2), QPointF(0, 1)] # scale points SCALE_FACTOR = 100 points = [p * SCALE_FACTOR for p in points] # create polygon self.polygon = QPolygonF(points) # create QGraphicsPolygonItem self.available_area = QGraphicsPolygonItem(self.polygon, self) self.available_area.setPen(QPen(Qt.DotLine)) # move the polygon poly_center = QPointF(1.5 * SCALE_FACTOR, 1.5 * SCALE_FACTOR) poly_center = self.mapToScene(poly_center) store_center = QPointF(self.x() + 40, self.y() + 40) ln = QLineF(poly_center, store_center) self.available_area.setPos(self.x() + ln.dx(), self.y() + ln.dy()) # connect the timer to acquire_champion self.timer = QTimer() self.timer.timeout.connect(self.acquire_champion) self.timer.start(1000)
def paint(self, painter): line = QLineF(self.sourcePoint, self.destPoint) if line.length() == 0.0: return painter.setPen( QPen(Qt.darkGray, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(line) angle = acos(line.dx() / line.length()) if line.dy() >= 0: angle = (2 * pi) - angle destArrowP1 = self.destPoint + QPointF( sin(angle - pi / 3) * self.arrowSize, cos(angle - pi / 3) * self.arrowSize) destArrowP2 = self.destPoint + QPointF( sin(angle - pi + pi / 3) * self.arrowSize, cos(angle - pi + pi / 3) * self.arrowSize) painter.setBrush(Qt.darkGray) painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
def move_forward(self): '''Overwriting move forward so it does not evade obstacles ''' # move object if self.has_target: return if self.should_be_moving: ln = QLineF(self.pos(), self.destination) ln.setLength(self.speed) self.rotate_to_point(self.destination) # avoid collision colliding_items = self.collidingItems() for i in colliding_items: if isinstance(i, StaticGameObject): return # move object forward at current angle self.setPos(self.x() + ln.dx(), self.y() + ln.dy()) self.x_prev = self.pos().x() self.y_prev = self.pos().y()
def calculateForces(self): if not self.scene() or self.scene().mouseGrabberItem() is self: self.newPos = self.pos() return # Sum up all forces pushing this item away. xvel = 0.0 yvel = 0.0 for item in self.scene().items(): if not isinstance(item, Node): continue line = QLineF(self.mapFromItem(item, 0, 0), QPointF(0, 0)) dx = line.dx() dy = line.dy() l = 2.0 * (dx * dx + dy * dy) if l > 0: xvel += (dx * 150.0) / l yvel += (dy * 150.0) / l # Now subtract all forces pulling items together. weight = (len(self.edgeList) + 1) * 10.0 for edge in self.edgeList: if edge.sourceNode() is self: pos = self.mapFromItem(edge.destNode(), 0, 0) else: pos = self.mapFromItem(edge.sourceNode(), 0, 0) xvel += pos.x() / weight yvel += pos.y() / weight if qAbs(xvel) < 0.1 and qAbs(yvel) < 0.1: xvel = yvel = 0.0 sceneRect = self.scene().sceneRect() self.newPos = self.pos() + QPointF(xvel, yvel) self.newPos.setX(min(max(self.newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)) self.newPos.setY(min(max(self.newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10))