Python pyqtgraph.Point() Examples

The following are 30 code examples of pyqtgraph.Point(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module pyqtgraph , or try the search function .
Example #1
Source File: pyoptic.py    From tf-pose with Apache License 2.0 6 votes vote down vote up
def __init__(self, gitem, **params):
        ParamObj.__init__(self)
        pg.GraphicsObject.__init__(self) #, [0,0], [1,1])

        self.gitem = gitem
        self.surfaces = gitem.surfaces
        gitem.setParentItem(self)
        
        self.roi = pg.ROI([0,0], [1,1])
        self.roi.addRotateHandle([1, 1], [0.5, 0.5])
        self.roi.setParentItem(self)
        
        defaults = {
            'pos': Point(0,0),
            'angle': 0,
        }
        defaults.update(params)
        self._ior_cache = {}
        self.roi.sigRegionChanged.connect(self.roiChanged)
        self.setParams(**defaults) 
Example #2
Source File: pyoptic.py    From tf-pose with Apache License 2.0 6 votes vote down vote up
def paramStateChanged(self):
        """Some parameters of the optic have changed."""
        # Move graphics item
        self.gitem.setPos(Point(self['pos']))
        self.gitem.resetTransform()
        self.gitem.rotate(self['angle'])
        
        # Move ROI to match
        try:
            self.roi.sigRegionChanged.disconnect(self.roiChanged)
            br = self.gitem.boundingRect()
            o = self.gitem.mapToParent(br.topLeft())
            self.roi.setAngle(self['angle'])
            self.roi.setPos(o)
            self.roi.setSize([br.width(), br.height()])
        finally:
            self.roi.sigRegionChanged.connect(self.roiChanged)
        
        self.sigStateChanged.emit() 
Example #3
Source File: pyoptic.py    From tf-pose with Apache License 2.0 6 votes vote down vote up
def propagateRay(self, ray):
        """Refract, reflect, absorb, and/or scatter ray. This function may create and return new rays"""
        
        surface = self.surfaces[0]
        p1, ai = surface.intersectRay(ray)
        if p1 is not None:
            p1 = surface.mapToItem(ray, p1)
            rd = ray['dir']
            a1 = np.arctan2(rd[1], rd[0])
            ar = a1  + np.pi - 2*ai
            ray.setEnd(p1)
            dp = Point(np.cos(ar), np.sin(ar))
            ray = Ray(parent=ray, dir=dp)
        else:
            ray.setEnd(None)
        return [ray] 
Example #4
Source File: pyoptic.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 6 votes vote down vote up
def propagateRay(self, ray):
        """Refract, reflect, absorb, and/or scatter ray. This function may create and return new rays"""
        
        surface = self.surfaces[0]
        p1, ai = surface.intersectRay(ray)
        if p1 is not None:
            p1 = surface.mapToItem(ray, p1)
            rd = ray['dir']
            a1 = np.arctan2(rd[1], rd[0])
            ar = a1  + np.pi - 2*ai
            ray.setEnd(p1)
            dp = Point(np.cos(ar), np.sin(ar))
            ray = Ray(parent=ray, dir=dp)
        else:
            ray.setEnd(None)
        return [ray] 
Example #5
Source File: pyoptic.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 6 votes vote down vote up
def paramStateChanged(self):
        """Some parameters of the optic have changed."""
        # Move graphics item
        self.gitem.setPos(Point(self['pos']))
        self.gitem.resetTransform()
        self.gitem.rotate(self['angle'])
        
        # Move ROI to match
        try:
            self.roi.sigRegionChanged.disconnect(self.roiChanged)
            br = self.gitem.boundingRect()
            o = self.gitem.mapToParent(br.topLeft())
            self.roi.setAngle(self['angle'])
            self.roi.setPos(o)
            self.roi.setSize([br.width(), br.height()])
        finally:
            self.roi.sigRegionChanged.connect(self.roiChanged)
        
        self.sigStateChanged.emit() 
Example #6
Source File: pyoptic.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 6 votes vote down vote up
def __init__(self, gitem, **params):
        ParamObj.__init__(self)
        pg.GraphicsObject.__init__(self) #, [0,0], [1,1])

        self.gitem = gitem
        self.surfaces = gitem.surfaces
        gitem.setParentItem(self)
        
        self.roi = pg.ROI([0,0], [1,1])
        self.roi.addRotateHandle([1, 1], [0.5, 0.5])
        self.roi.setParentItem(self)
        
        defaults = {
            'pos': Point(0,0),
            'angle': 0,
        }
        defaults.update(params)
        self._ior_cache = {}
        self.roi.sigRegionChanged.connect(self.roiChanged)
        self.setParams(**defaults) 
Example #7
Source File: test_plotutils.py    From orange3-geo with GNU General Public License v3.0 6 votes vote down vote up
def test_mouse_drag_event(self):
        self.mock_graph.state = ZOOMING
        mock_event = Mock()
        mock_event.button.return_value = Qt.LeftButton
        mock_event.pos.return_value = pg.Point(0.6, 0.6)
        mock_event.isFinish.return_value = True
        mock_event.buttonDownPos.return_value = pg.Point(0.4, 0.4)
        self.mvb.mapToView = lambda x: x
        self.mvb.state['mouseMode'] = pg.ViewBox.RectMode

        self.mvb.match_zoom(pg.Point(0.5, 0.5))
        qrect1 = self.sr.call_args[0][0]
        zoom1 = self.mvb.get_zoom()
        self.mvb.mouseDragEvent(mock_event)
        mock_event.accept.assert_called()
        zoom2 = self.mvb.get_zoom()
        qrect2 = self.sr.call_args[0][0]
        # when selecting a smaller region zoom level should increase and
        # shown area should decrees
        self.assertTrue(zoom2 > zoom1)
        self.assertTrue(qrect2.width() < qrect1.width())

        mock_event.button.return_value = Qt.RightButton
        self.mvb.mouseDragEvent(mock_event)
        mock_event.ignore.assert_called() 
Example #8
Source File: __init__.py    From finplot with MIT License 6 votes vote down vote up
def wheelEvent(self, ev, axis=None):
        if ev.modifiers() == QtCore.Qt.ControlModifier:
            scale_fact = 1
            self.v_zoom_scale /= 1.02 ** (ev.delta() * self.state['wheelScaleFactor'])
        else:
            scale_fact = 1.02 ** (ev.delta() * self.state['wheelScaleFactor'])
        vr = self.targetRect()
        center = self.mapToView(ev.pos())
        if (center.x()-vr.left())/vr.width() < 0.05: # zoom to far left => all the way left
            center = pg.Point(vr.left(), center.y())
        elif (center.x()-vr.left())/vr.width() > 0.95: # zoom to far right => all the way right
            center = pg.Point(vr.right(), center.y())
        self.zoom_rect(vr, scale_fact, center)
        # update crosshair
        _mouse_moved(self.win, None)
        ev.accept() 
Example #9
Source File: test_InfiniteLine.py    From soapy with GNU General Public License v3.0 5 votes vote down vote up
def test_InfiniteLine():
    # Test basic InfiniteLine API
    plt = pg.plot()
    plt.setXRange(-10, 10)
    plt.setYRange(-10, 10)
    plt.resize(600, 600)
    
    # seemingly arbitrary requirements; might need longer wait time for some platforms..
    QtTest.QTest.qWaitForWindowShown(plt)
    QtTest.QTest.qWait(100)
    
    vline = plt.addLine(x=1)
    assert vline.angle == 90
    br = vline.mapToView(QtGui.QPolygonF(vline.boundingRect()))
    assert br.containsPoint(pg.Point(1, 5), QtCore.Qt.OddEvenFill)
    assert not br.containsPoint(pg.Point(5, 0), QtCore.Qt.OddEvenFill)
    hline = plt.addLine(y=0)
    assert hline.angle == 0
    assert hline.boundingRect().contains(pg.Point(5, 0))
    assert not hline.boundingRect().contains(pg.Point(0, 5))

    vline.setValue(2)
    assert vline.value() == 2
    vline.setPos(pg.Point(4, -5))
    assert vline.value() == 4
    
    oline = pg.InfiniteLine(angle=30)
    plt.addItem(oline)
    oline.setPos(pg.Point(1, -1))
    assert oline.angle == 30
    assert oline.pos() == pg.Point(1, -1)
    assert oline.value() == [1, -1]
    
    # test bounding rect for oblique line
    br = oline.mapToScene(oline.boundingRect())
    pos = oline.mapToScene(pg.Point(2, 0))
    assert br.containsPoint(pos, QtCore.Qt.OddEvenFill)
    px = pg.Point(-0.5, -1.0 / 3**0.5)
    assert br.containsPoint(pos + 5 * px, QtCore.Qt.OddEvenFill)
    assert not br.containsPoint(pos + 7 * px, QtCore.Qt.OddEvenFill) 
Example #10
Source File: plotutils.py    From orange3-geo with GNU General Public License v3.0 5 votes vote down vote up
def _update_view_range(self, min_x, max_x, min_y, max_y, keep_zoom=False):
        if not keep_zoom:
            self.view_box.recalculate_zoom(max_x - min_x, max_y - min_y)

        center = Point(min_x + (max_x - min_x) / 2,
                       min_y + (max_y - min_y) / 2)
        self.view_box.match_zoom(center) 
Example #11
Source File: graphics.py    From suite2p with GNU General Public License v3.0 5 votes vote down vote up
def mouseDragEvent(self, ev, axis=None):
        ## if axis is specified, event will only affect that axis.
        ev.accept()  ## we accept all buttons

        pos = ev.pos()
        lastPos = ev.lastPos()
        dif = pos - lastPos
        dif = dif * -1

        ## Ignore axes if mouse is disabled
        mouseEnabled = np.array(self.state['mouseEnabled'], dtype=np.float)
        mask = mouseEnabled.copy()
        if axis is not None:
            mask[1-axis] = 0.0

        ## Scale or translate based on mouse button
        if ev.button() & (QtCore.Qt.LeftButton | QtCore.Qt.MidButton):
            if self.state['mouseMode'] == pg.ViewBox.RectMode:
                if ev.isFinish():  ## This is the final move in the drag; change the view scale now
                    #print "finish"
                    self.rbScaleBox.hide()
                    ax = QtCore.QRectF(Point(ev.buttonDownPos(ev.button())), Point(pos))
                    ax = self.childGroup.mapRectFromParent(ax)
                    self.showAxRect(ax)
                    self.axHistoryPointer += 1
                    self.axHistory = self.axHistory[:self.axHistoryPointer] + [ax]
                else:
                    ## update shape of scale box
                    self.updateScaleBox(ev.buttonDownPos(), ev.pos())
            else:
                tr = dif*mask
                tr = self.mapToView(tr) - self.mapToView(Point(0,0))
                x = tr.x() if mask[0] == 1 else None
                y = tr.y() if mask[1] == 1 else None

                self._resetTarget()
                if x is not None or y is not None:
                    self.translateBy(x=x, y=y)
                self.sigRangeChangedManually.emit(self.state['mouseEnabled']) 
Example #12
Source File: __init__.py    From finplot with MIT License 5 votes vote down vote up
def mouseMiddleDrag(self, ev, axis):
        if ev.modifiers() != QtCore.Qt.ControlModifier:
            return super().mouseDragEvent(ev, axis)
        p1 = self.mapToView(ev.pos())
        p1 = _clamp_point(self.parent(), p1)
        def nonzerosize(a, b):
            c = b-a
            return pg.Point(abs(c.x()) or 1, abs(c.y()) or 1)
        if not self.drawing:
            # add new line
            p0 = self.mapToView(ev.lastPos())
            p0 = _clamp_point(self.parent(), p0)
            s = nonzerosize(p0, p1)
            self.draw_ellipse = FinEllipse(p0, s, pen=pg.mkPen(draw_line_color), movable=True)
            self.draw_ellipse.setZValue(80)
            self.rois.append(self.draw_ellipse)
            self.addItem(self.draw_ellipse)
            self.drawing = True
        else:
            c = self.draw_ellipse.pos() + self.draw_ellipse.size()*0.5
            s = nonzerosize(c, p1)
            self.draw_ellipse.setSize(s*2, update=False)
            self.draw_ellipse.setPos(c-s)
        if ev.isFinish():
            self.drawing = False
        ev.accept() 
Example #13
Source File: __init__.py    From finplot with MIT License 5 votes vote down vote up
def set_range(self, x0, y0, x1, y1):
        if x0 is None or x1 is None:
            tr = self.targetRect()
            x0 = tr.left()
            x1 = tr.right()
        if np.isnan(y0) or np.isnan(y1):
            return
        _y0 = self.yscale.invxform(y0, verify=True)
        _y1 = self.yscale.invxform(y1, verify=True)
        self.setRange(QtCore.QRectF(pg.Point(x0, _y0), pg.Point(x1, _y1)), padding=0) 
Example #14
Source File: __init__.py    From finplot with MIT License 5 votes vote down vote up
def _clamp_point(ax, p):
    if clamp_grid:
        x,y = _clamp_xy(ax, p.x(), p.y())
        return pg.Point(x, y)
    return p 
Example #15
Source File: plotutils.py    From orange3-geo with GNU General Public License v3.0 5 votes vote down vote up
def match_zoom(self, center: Point, offset=False):
        """
        Find the right rectangle of visualization so that maps and
        screens resolutions match.
        :param center: center point of the new rectangle
        :param offset: set true if center is offset so the visualization
        doesn't jump around (used from zooming)
        """
        new_target = self.__new_target(center, offset=offset)
        self.setRange(new_target, padding=0)
        self.sigRangeChangedManually.emit(self.state['mouseEnabled']) 
Example #16
Source File: pyoptic.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def updateTransform(self):
        self.resetTransform()
        self.setPos(0, 0)
        self.translate(Point(self['pos']))
        self.rotate(self['angle']) 
Example #17
Source File: pyoptic.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def currentState(self, relativeTo=None):
        pos = self['start']
        dir = self['dir']
        if relativeTo is None:
            return pos, dir
        else:
            trans = self.itemTransform(relativeTo)[0]
            p1 = trans.map(pos)
            p2 = trans.map(pos + dir)
            return Point(p1), Point(p2-p1) 
Example #18
Source File: relativity.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def stepTo(self, t):
        data = self.clock.refData
        
        while self.i < len(data)-1 and data['t'][self.i] < t:
            self.i += 1
        while self.i > 1 and data['t'][self.i-1] >= t:
            self.i -= 1
        
        self.setPos(data['x'][self.i], self.clock.y0)
        
        t = data['pt'][self.i]
        self.hand.setRotation(-0.25 * t * 360.)
        
        self.resetTransform()
        v = data['v'][self.i]
        gam = (1.0 - v**2)**0.5
        self.scale(gam, 1.0)
        
        f = data['f'][self.i]
        self.flare.resetTransform()
        if f < 0:
            self.flare.translate(self.size*0.4, 0)
        else:
            self.flare.translate(-self.size*0.4, 0)
        
        self.flare.scale(-f * (0.5+np.random.random()*0.1), 1.0)
        
        if self._spaceline is not None:
            self._spaceline.setPos(pg.Point(data['x'][self.i], data['t'][self.i]))
            self._spaceline.setAngle(data['v'][self.i] * 45.) 
Example #19
Source File: plotutils.py    From orange3-geo with GNU General Public License v3.0 5 votes vote down vote up
def __new_target(self, center, offset=False):
        """Get new rectangle centered around center."""
        dx, dy = self.__get_size()
        left_size, up_size = 0.5, 0.5

        if offset:
            # offset target rectangle size, more natural for zooming
            vr = self.targetRect()
            left_size = (center.x() - vr.topLeft().x()) / vr.width()
            up_size = (center.y() - vr.topLeft().y()) / vr.height()

        tl = center + Point(-dx * left_size, -dy * up_size)
        br = center + Point(dx * (1 - left_size), dy * (1 - up_size))
        return QRectF(tl, br) 
Example #20
Source File: test_owmap.py    From orange3-geo with GNU General Public License v3.0 5 votes vote down vote up
def test_update_view_range(self):
        self.graph.reset_graph()
        self.view_box.recalculate_zoom.reset_mock()
        self.view_box.match_zoom.reset_mock()

        self.graph.update_view_range()
        self.view_box.recalculate_zoom.assert_called_once_with(0.7 - 0.5,
                                                               0.8 - 0.6)
        self.view_box.match_zoom.assert_called_once_with(Point(0.6, 0.7))

        self.view_box.recalculate_zoom.reset_mock()
        self.view_box.match_zoom.reset_mock()
        self.graph.update_view_range(match_data=False)
        self.assertFalse(self.view_box.recalculate_zoom.called)
        self.view_box.match_zoom.assert_called_once_with(Point(0.15, 0.35)) 
Example #21
Source File: test_owmap.py    From orange3-geo with GNU General Public License v3.0 5 votes vote down vote up
def test_no_data(self):
        self.xy = None, None
        self.graph.reset_graph()
        self.view_box.recalculate_zoom.assert_called_once_with(1, 1)
        self.view_box.match_zoom.assert_called_once_with(Point(0.5, 0.5)) 
Example #22
Source File: test_plotutils.py    From orange3-geo with GNU General Public License v3.0 5 votes vote down vote up
def test_wheel_event(self):
        mock_event = Mock()
        mock_event.delta.return_value = 1
        mock_event.pos.return_value = pg.Point(0.5, 0.5)

        self.assertEqual(self.mvb.get_zoom(), 2)
        self.mvb.wheelEvent(mock_event)
        self.assertEqual(self.mvb.get_zoom(), 3)
        qrect1 = self.sr.call_args[0][0]
        mock_event.accept.assert_called()
        self.mvb.wheelEvent(mock_event)
        self.assertEqual(self.mvb.get_zoom(), 4)
        qrect2 = self.sr.call_args[0][0]
        # after zooming in the shown rectangle should be smaller
        self.assertTrue(qrect1.width() > qrect2.width())

        mock_event.delta.return_value = -1
        self.mvb.wheelEvent(mock_event)
        self.assertEqual(self.mvb.get_zoom(), 3)
        qrect3 = self.sr.call_args[0][0]
        # after zooming out the shown rectangle should be larger
        self.assertTrue(qrect3.width() > qrect2.width())

        self.mvb.wheelEvent(mock_event)
        self.mvb.wheelEvent(mock_event)
        self.assertEqual(self.mvb.get_zoom(), 2) 
Example #23
Source File: test_plotutils.py    From orange3-geo with GNU General Public License v3.0 5 votes vote down vote up
def test_match_zoom(self):
        point1 = pg.Point(0.5, 0.5)
        self.mvb.match_zoom(point1)
        qrect1 = self.sr.call_args[0][0]

        point2 = pg.Point(0.75, 0.75)
        self.mvb.match_zoom(point2, offset=True)
        qrect2 = self.sr.call_args[0][0]
        # when center is offset the new rect should also be offset
        self.assertTrue(qrect1.x() < qrect2.x())
        self.assertAlmostEqual(qrect1.width(), qrect2.width()) 
Example #24
Source File: base.py    From kite with GNU General Public License v3.0 5 votes vote down vote up
def updateROIPosition(self):
        source = self.source
        self.setPos(
            pg.Point((source.easting - self.size().x()/2,
                      source.northing - self.size().x()/2)),
            finish=False) 
Example #25
Source File: base.py    From kite with GNU General Public License v3.0 5 votes vote down vote up
def updateROIPosition(self):
        source = self.source
        width = source.width

        self.setPos(
            pg.Point(source.outline()[1]),
            finish=False)
        self.setSize(
            pg.Point(width, source.length),
            finish=False)
        self.setAngle(
            -source.strike,
            finish=False) 
Example #26
Source File: base.py    From kite with GNU General Public License v3.0 5 votes vote down vote up
def __init__(self, delegate):
        self.delegate = delegate
        self.source = self.delegate.source
        source = self.source

        pg.ROI.__init__(
            self,
            pos=pg.Point(source.outline()[1]),
            size=pg.Point(source.width, source.length),
            angle=-source.strike,
            invertible=False,
            pen=self.pen_outline)
        self.handlePen = self.pen_handle

        self.addScaleRotateHandle([0, 0], [0, 1])
        self.addScaleRotateHandle([0, 1], [0, 0])
        self.addScaleHandle([1, .5], [0, .5],
                            lockAspect=False)

        for h in self.handles:
            h['item'].sigClicked.connect(self.sigRegionChangeStarted.emit)

        self.delegate.sourceParametersChanged.connect(
            self.updateROIPosition)
        self.sigRegionChangeFinished.connect(
            self.setSourceParametersFromROI)

        self.setAcceptedMouseButtons(QtCore.Qt.RightButton)
        self.sigClicked.connect(self.showEditingDialog) 
Example #27
Source File: test_InfiniteLine.py    From tf-pose with Apache License 2.0 5 votes vote down vote up
def test_InfiniteLine():
    # Test basic InfiniteLine API
    plt = pg.plot()
    plt.setXRange(-10, 10)
    plt.setYRange(-10, 10)
    plt.resize(600, 600)
    
    # seemingly arbitrary requirements; might need longer wait time for some platforms..
    QtTest.QTest.qWaitForWindowShown(plt)
    QtTest.QTest.qWait(100)
    
    vline = plt.addLine(x=1)
    assert vline.angle == 90
    br = vline.mapToView(QtGui.QPolygonF(vline.boundingRect()))
    assert br.containsPoint(pg.Point(1, 5), QtCore.Qt.OddEvenFill)
    assert not br.containsPoint(pg.Point(5, 0), QtCore.Qt.OddEvenFill)
    hline = plt.addLine(y=0)
    assert hline.angle == 0
    assert hline.boundingRect().contains(pg.Point(5, 0))
    assert not hline.boundingRect().contains(pg.Point(0, 5))

    vline.setValue(2)
    assert vline.value() == 2
    vline.setPos(pg.Point(4, -5))
    assert vline.value() == 4
    
    oline = pg.InfiniteLine(angle=30)
    plt.addItem(oline)
    oline.setPos(pg.Point(1, -1))
    assert oline.angle == 30
    assert oline.pos() == pg.Point(1, -1)
    assert oline.value() == [1, -1]
    
    # test bounding rect for oblique line
    br = oline.mapToScene(oline.boundingRect())
    pos = oline.mapToScene(pg.Point(2, 0))
    assert br.containsPoint(pos, QtCore.Qt.OddEvenFill)
    px = pg.Point(-0.5, -1.0 / 3**0.5)
    assert br.containsPoint(pos + 5 * px, QtCore.Qt.OddEvenFill)
    assert not br.containsPoint(pos + 7 * px, QtCore.Qt.OddEvenFill) 
Example #28
Source File: relativity.py    From tf-pose with Apache License 2.0 5 votes vote down vote up
def stepTo(self, t):
        data = self.clock.refData
        
        while self.i < len(data)-1 and data['t'][self.i] < t:
            self.i += 1
        while self.i > 1 and data['t'][self.i-1] >= t:
            self.i -= 1
        
        self.setPos(data['x'][self.i], self.clock.y0)
        
        t = data['pt'][self.i]
        self.hand.setRotation(-0.25 * t * 360.)
        
        self.resetTransform()
        v = data['v'][self.i]
        gam = (1.0 - v**2)**0.5
        self.scale(gam, 1.0)
        
        f = data['f'][self.i]
        self.flare.resetTransform()
        if f < 0:
            self.flare.translate(self.size*0.4, 0)
        else:
            self.flare.translate(-self.size*0.4, 0)
        
        self.flare.scale(-f * (0.5+np.random.random()*0.1), 1.0)
        
        if self._spaceline is not None:
            self._spaceline.setPos(pg.Point(data['x'][self.i], data['t'][self.i]))
            self._spaceline.setAngle(data['v'][self.i] * 45.) 
Example #29
Source File: pyoptic.py    From tf-pose with Apache License 2.0 5 votes vote down vote up
def currentState(self, relativeTo=None):
        pos = self['start']
        dir = self['dir']
        if relativeTo is None:
            return pos, dir
        else:
            trans = self.itemTransform(relativeTo)[0]
            p1 = trans.map(pos)
            p2 = trans.map(pos + dir)
            return Point(p1), Point(p2-p1) 
Example #30
Source File: pyoptic.py    From tf-pose with Apache License 2.0 5 votes vote down vote up
def updateTransform(self):
        self.resetTransform()
        self.setPos(0, 0)
        self.translate(Point(self['pos']))
        self.rotate(self['angle'])