Beispiel #1
0
 def __init__(self,
              lat,
              lon,
              name="",
              phoneNumbers=None,
              urls=None,
              addressLines=None,
              emails=None,
              openingHours=None,
              priceLevel=None,
              rating=None):
     if not emails: emails = []
     if not addressLines: addressLines = []
     if not urls: urls = []
     if not phoneNumbers: phoneNumbers = []
     if not openingHours: openingHours = {}
     Point.__init__(self, lat, lon, name=name)
     self._message_loaded = False
     self._phoneNumbers = phoneNumbers
     self._urls = urls
     self._addressLines = addressLines
     self._emails = emails
     self._openingHours = openingHours
     self._priceLevel = priceLevel
     self._rating = rating
Beispiel #2
0
    def __init__(self, Ps=Point(0, 0), Pe=Point(0, 0), hdl=[]):
        """ 
        Standard method to initialize the class
        """

        self.Ps = Ps
        self.Pe = Pe
Beispiel #3
0
    def __init__(self, parent=None):
        super(GLWidget, self).__init__(parent)

        self.shapes = Shapes([])
        self.orientation = 0
        self.wpZero = 0
        self.routearrows = []
        self.expprv = None

        self.isPanning = False
        self.isRotating = False
        self.isMultiSelect = False
        self._lastPos = QPoint()

        self.posX = 0.0
        self.posY = 0.0
        self.posZ = 0.0
        self.rotX = 0.0
        self.rotY = 0.0
        self.rotZ = 0.0
        self.scale = 1.0
        self.scaleCorr = 1.0

        self.showPathDirections = False
        self.showDisabledPaths = False

        self.topLeft = Point()
        self.bottomRight = Point()

        self.tol = 0
Beispiel #4
0
 def get_start_end_points(self, start_point, angles=None):
     if angles is None:
         return self
     elif angles:
         return self, 0
     else:
         return self, Point(0, -1) if start_point else Point(0, -1)
Beispiel #5
0
    def bulge2arc(self, Ps, Pe, bulge):
        """
        bulge2arc()
        """
        c = (1 / bulge - bulge) / 2

        # Berechnung des Mittelpunkts (Formel von Mickes!)
        # Calculation of the center (Micke's formula)
        O = Point((Ps.x + Pe.x - (Pe.y - Ps.y) * c) / 2,
                  (Ps.y + Pe.y + (Pe.x - Ps.x) * c) / 2)

        # Radius = Distance between the centre and Ps
        r = O.distance(Ps)
        # Kontrolle ob beide gleich sind (passt ...)
        # Check if they are equal (fits ...)
        # r=O.distance(Pe)

        # Unterscheidung f�r den �ffnungswinkel.
        # Distinction for the opening angle. ???
        if bulge > 0:
            return ArcGeo(Ps=Ps, Pe=Pe, O=O, r=r)
        else:
            arc = ArcGeo(Ps=Pe, Pe=Ps, O=O, r=r)
            arc.reverse()
            return arc
Beispiel #6
0
    def __init__(self, parent=None):
        super(GLWidget, self).__init__(parent)

        self.shapes = Shapes([])
        self.orientation = 0
        self.wpZero = 0
        self.routearrows = []
        self.expprv = None

        self.isPanning = False
        self.isRotating = False
        self.isMultiSelect = False
        self._lastPos = QPoint()

        self.posX = 0.0
        self.posY = 0.0
        self.posZ = 0.0
        self.rotX = 0.0
        self.rotY = 0.0
        self.rotZ = 0.0
        self.scale = 1.0
        self.scaleCorr = 1.0

        self.showPathDirections = False
        self.showDisabledPaths = False

        self.topLeft = Point()
        self.bottomRight = Point()

        self.tol = 0
Beispiel #7
0
 def clear_test(self):
     """Test if the clear() methods of the Way class works correctly."""
     # put some regular points to the way first
     first = (0.0, 0.0, 0.0)
     second = (1.0, 1.0, 100.0)
     third = (2.0, 2.0, 200.0)
     lle_list = [first, second, third]
     way = Way(points=lle_list)
     # add some message points
     point1 = Point(lat=50.0, lon=50.0, elevation=300.0, message="foo")
     point2 = Point(lat=75.0, lon=75.0, elevation=600.0, message="bar")
     way.add_message_point(point1)
     way.add_message_point(point2)
     # check there are points & message points
     self.assertEqual(way.point_count, 3)
     self.assertEqual(way.message_point_count, 2)
     self.assertTrue(len(way.points_lle) > 0)
     self.assertTrue(len(way.message_points) > 0)
     self.assertTrue(len(way.message_points_lle) > 0)
     # call the clear methods
     way.clear()
     way.clear_message_points()
     # check that the way is empty
     self.assertEqual(way.point_count, 0)
     self.assertEqual(way.message_point_count, 0)
     self.assertListEqual(way.points_lle, [])
     self.assertListEqual(way.message_points, [])
     self.assertListEqual(way.message_points_lle, [])
Beispiel #8
0
    def drawOrientationArrows(self):

        rCone = 0.01
        rCylinder = 0.004
        zTop = 0.05
        zMiddle = 0.02
        zBottom = -0.03
        segments = 20

        arrow = GL.glGenLists(1)
        GL.glNewList(arrow, GL.GL_COMPILE)

        self.drawCone(Point(), rCone, zTop, zMiddle, segments)
        self.drawSolidCircle(Point(), rCone, zMiddle, segments)
        self.drawCylinder(Point(), rCylinder, zMiddle, zBottom, segments)
        self.drawSolidCircle(Point(), rCylinder, zBottom, segments)

        GL.glEndList()

        self.orientation = GL.glGenLists(1)
        GL.glNewList(self.orientation, GL.GL_COMPILE)

        self.setColorRGBA(0.0, 0.0, 1.0, 0.5)
        GL.glCallList(arrow)

        GL.glRotatef(90, 0, 1, 0)
        self.setColorRGBA(1.0, 0.0, 0.0, 0.5)
        GL.glCallList(arrow)

        GL.glRotatef(90, 1, 0, 0)
        self.setColorRGBA(0.0, 1.0, 0.0, 0.5)
        GL.glCallList(arrow)

        GL.glEndList()
Beispiel #9
0
    def drawWpZero(self):

        r = 0.02
        segments = 20  # must be a multiple of 4

        self.wpZero = GL.glGenLists(1)
        GL.glNewList(self.wpZero, GL.GL_COMPILE)

        self.setColorRGBA(0.2, 0.2, 0.2, 0.7)
        self.drawSphere(r, segments, segments // 4, segments, segments // 4)

        GL.glBegin(GL.GL_TRIANGLE_FAN)
        GL.glVertex3f(0, 0, 0)
        for i in range(segments // 4 + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r)
            # GL.glNormal3f(0, -1, 0)
            GL.glVertex3f(xy2.x, 0, xy2.y)
        for i in range(segments // 4 + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r)
            # GL.glNormal3f(-1, 0, 0)
            GL.glVertex3f(0, -xy2.y, -xy2.x)
        for i in range(segments // 4 + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r)
            # GL.glNormal3f(0, 0, 1)
            GL.glVertex3f(-xy2.y, xy2.x, 0)
        GL.glEnd()

        self.setColorRGBA(0.6, 0.6, 0.6, 0.5)
        self.drawSphere(r * 1.25, segments, segments, segments, segments)

        GL.glEndList()
Beispiel #10
0
    def drawArrowHead(self, origin, rx, ry, rz, offset):
        r = 0.01
        segments = 10
        zTop = 0 + offset
        zBottom = -0.02 + offset

        GL.glBegin(GL.GL_TRIANGLE_FAN)
        zeroTop = Point3D(0, 0, zTop)
        GL.glVertex3f(zeroTop * rx + origin.x, -zeroTop * ry - origin.y,
                      zeroTop * rz + origin.z)
        for i in range(segments + 1):
            ang = i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r).to3D(zBottom)
            GL.glVertex3f(xy2 * rx + origin.x, -xy2 * ry - origin.y,
                          xy2 * rz + origin.z)
        GL.glEnd()

        GL.glBegin(GL.GL_TRIANGLE_FAN)
        zeroBottom = Point3D(0, 0, zBottom)
        GL.glVertex3f(zeroBottom * rx + origin.x, -zeroBottom * ry - origin.y,
                      zeroBottom * rz + origin.z)
        for i in range(segments + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r).to3D(zBottom)
            GL.glVertex3f(xy2 * rx + origin.x, -xy2 * ry - origin.y,
                          xy2 * rz + origin.z)
        GL.glEnd()
Beispiel #11
0
    def __init__(self, Nr=0, caller=None):
        self.Typ = 'Ellipse'
        self.Nr = Nr
        # Initialisieren der Werte
        # Initialise the values
        self.Layer_Nr = 0
        self.center = Point(0, 0)  # Centre of the geometry
        self.vector = Point(1, 0)  #  Vector A = semi-major axis.
        #  a = rotation of the ellipse
        #  http://de.wikipedia.org/wiki/Gro%C3%9Fe_Halbachse
        self.ratio = 1  # Verh�ltnis der kleinen zur gro�en Halbachse (b/a)
        # Ratio of the minor to major axis (b/a)
        # self.AngS = 0            # Startwinkel beim zeichnen eines Ellipsensegments
        # Starting angle when drawing an ellipse segment
        # self.AngE = radians(360) # Endwinkel (Winkel im DXF als Radians!)
        # End angle (angle in radians as DXF!)
        # Die folgenden Grundwerte werden sp�ter ein mal berechnet
        # The following limits are calculated later

        self.length = 0
        self.Points = []
        self.Points.append(self.center)
        # Lesen der Geometrie / Read the geometry
        self.Read(caller)

        # Zuweisen der Toleranz f�rs Fitting / Assign the tolerance for fitting
        tol = g.config.fitting_tolerance

        # Errechnen der Ellipse / Calculate the ellipse
        self.Ellipse_Grundwerte()
        self.Ellipse_2_Arcs(tol)
Beispiel #12
0
    def bulge2arc(self, Ps, Pe, bulge):
        """
        bulge2arc()
        """
        c = (1 / bulge - bulge) / 2

        # Berechnung des Mittelpunkts (Formel von Mickes!)
        # Calculation of the center (Micke's formula)
        O = Point((Ps.x + Pe.x - (Pe.y - Ps.y) * c) / 2,
                  (Ps.y + Pe.y + (Pe.x - Ps.x) * c) / 2)

        # Radius = Distance between the centre and Ps
        r = O.distance(Ps)
        # Kontrolle ob beide gleich sind (passt ...)
        # Check if they are equal (fits ...)
        # r=O.distance(Pe)

        # Unterscheidung f�r den �ffnungswinkel.
        # Distinction for the opening angle. ???
        if bulge > 0:
            return ArcGeo(Ps=Ps, Pe=Pe, O=O, r=r)
        else:
            arc = ArcGeo(Ps=Pe, Pe=Ps, O=O, r=r)
            arc.reverse()
            return arc
Beispiel #13
0
    def calc_bounding_box(self):
        """
        Calculated the BoundingBox of the geometry and saves it into self.BB
        """
        Ps = Point(x=min(self.Ps.x, self.Pe.x), y=min(self.Ps.y, self.Pe.y))
        Pe = Point(x=max(self.Ps.x, self.Pe.x), y=max(self.Ps.y, self.Pe.y))

        self.BB = BoundingBox(Ps=Ps, Pe=Pe)
Beispiel #14
0
    def calc_bounding_box(self, radius=1):
        """
        Calculated the BoundingBox of the geometry and saves it into self.BB
        @param radius: The Radius of the HoleGeo to be used for BoundingBox
        """

        Ps = Point(x=self.Ps.x - radius, y=self.Ps.y - radius)
        Pe = Point(x=self.Ps.x + radius, y=self.Ps.y + radius)

        self.BB = BoundingBox(Ps=Ps, Pe=Pe)
Beispiel #15
0
 def lat_lon_only_point_test(self):
     """Test that a lat-lon-only point can be created"""
     point = Point(1.0, 2.0)
     self.assertEqual(point.lat, 1.0)
     self.assertEqual(point.lon, 2.0)
     self.assertIsNone(point.name)
     self.assertEqual(point.summary, "")
     self.assertIsNone(point.description)
     self.assertIsNone(point.elevation)
     self.assertEqual(point.getUrls(), [])
Beispiel #16
0
 def lat_lon_only_point_test(self):
     """Test that a lat-lon-only point can be created"""
     point = Point(1.0, 2.0)
     self.assertEqual(point.lat, 1.0)
     self.assertEqual(point.lon, 2.0)
     self.assertIsNone(point.name)
     self.assertEqual(point.summary, "")
     self.assertIsNone(point.description)
     self.assertIsNone(point.elevation)
     self.assertEqual(point.getUrls(), [])
Beispiel #17
0
    def Read(self, caller):
        """
        Read()
        """

        # Assign short name
        lp = caller.line_pairs
        e = lp.index_code(0, caller.start + 1)

        # Assign layer
        s = lp.index_code(8, caller.start + 1)
        self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value)

        # X Value
        s = lp.index_code(10, s + 1)
        x0 = float(lp.line_pair[s].value)

        # Y Value
        s = lp.index_code(20, s + 1)
        y0 = float(lp.line_pair[s].value)

        # Radius
        s = lp.index_code(40, s + 1)
        r = float(lp.line_pair[s].value)

        # Searching for an extrusion direction
        s_nxt_xt = lp.index_code(230, s + 1, e)
        # If there is a extrusion direction given flip around x-Axis
        if s_nxt_xt is not None:
            extrusion_dir = float(lp.line_pair[s_nxt_xt].value)
            logger.debug(self.tr('Found extrusion direction: %s') % extrusion_dir)
            if extrusion_dir == -1:
                x0 = -x0

        O = Point(x0, y0)

        # Calculate the start and end values of the circle without clipping
        s_ang = -3 * pi / 4
        m_ang = s_ang - pi
        e_ang = -3 * pi / 4

        # Calculate the start and end values of the arcs
        Ps = Point(cos(s_ang) * r, sin(s_ang) * r) + O
        Pm = Point(cos(m_ang) * r, sin(m_ang) * r) + O
        Pe = Point(cos(e_ang) * r, sin(e_ang) * r) + O

        # Annexes to ArcGeo class for geometry
        self.geo.append(ArcGeo(Ps=Ps, Pe=Pm, O=O, r=r, s_ang=s_ang, e_ang=m_ang, direction=-1))
        self.geo.append(ArcGeo(Ps=Pm, Pe=Pe, O=O, r=r, s_ang=m_ang, e_ang=e_ang, direction=-1))

        # Length corresponds to the length (circumference?) of the circle
        self.length = self.geo[-1].length+self.geo[-2].length

        # New starting value for the next geometry
        caller.start = s
Beispiel #18
0
    def _earlyLocalSearch(self):
        """handle CLI initiated local search that returns a static map URL"""
        # for local search, we need to know our position, so we need at least the
        # location module and of also of course the online services module to do the search

        self._disableStdout()

        # local search need Internet connectivity, trigger
        # Internet initialization now, the search function decorator
        # will wait for it to finish
        self.modrana.dmod.enable_internet_connectivity()

        # load the online services module
        online = self.modrana._load_module("mod_onlineServices",
                                           "onlineServices")

        query = self.args.local_search
        points = []  # points defining the result/s

        # now check if a location for the local search was provided from CLI or if we need to find our location
        # using GPS or equivalent

        from core.point import Point

        location = self._getLocalSearchLocation()
        if location is not None:
            # we use the location provided from CLI, no need to load & start location
            if self._useLastKnownPos(location):
                # get last known position (if any)
                pos = self._getCurrentPosition(loadLocationModule=True,
                                               useLastKnown=True)
                if pos is None:
                    self._enableStdout()
                    log.error("no last known position available")
                    # done - no position found
                    self._exit(LOCAL_SEARCH_CURRENT_POSITION_UNKNOWN_ERROR)
                else:
                    lat, lon = pos
                    # replace the use-last-known flag with the actual location
                    location = Point(lat, lon)
        else:
            # we need to determine our current location - the location module needs to be loaded & used
            pos = self._getCurrentPosition(loadLocationModule=True)
            if pos is not None:
                lat, lon = pos
                location = Point(lat, lon)
            else:
                # done - no position found
                self._exit(LOCAL_SEARCH_CURRENT_POSITION_UNKNOWN_ERROR)

        # do the search
        points = online.localSearch(query, location)

        # local search results processing
        self._returnStaticMapUrl(points, online)
Beispiel #19
0
 def __init__(self,
              lat,
              lon,
              elevation=None,
              message=None,
              SSMLMessage=None):
     Point.__init__(self, lat, lon, elevation=elevation, message=message)
     self.currentDistance = None  # in meters
     self.distanceFromStart = None  # in meters
     self.visited = False
     self.SSMLMessage = SSMLMessage
    def Read(self, caller):
        """
        This function does read the geometry.
        @param caller: The instance which is calling the function
        """
        # Assign short name
        lp = caller.line_pairs
        e = lp.index_code(0, caller.start + 1)

        # Assign layer
        s = lp.index_code(8, caller.start + 1)
        self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value)

        # X Value
        sl = lp.index_code(10, s + 1)
        x0 = float(lp.line_pair[sl].value)

        # Y Value
        s = lp.index_code(20, sl + 1)
        y0 = float(lp.line_pair[s].value)

        # X Value 2
        s = lp.index_code(11, sl + 1)
        x1 = float(lp.line_pair[s].value)

        # Y Value 2
        s = lp.index_code(21, s + 1)
        y1 = float(lp.line_pair[s].value)

        # Searching for an extrusion direction
        s_nxt_xt = lp.index_code(230, s + 1, e)
        # If there is a extrusion direction given flip around x-Axis
        if s_nxt_xt is not None:
            extrusion_dir = float(lp.line_pair[s_nxt_xt].value)
            logger.debug(
                self.tr('Found extrusion direction: %s') % extrusion_dir)
            if extrusion_dir == -1:
                x0 = -x0
                x1 = -x1

        Ps = Point(x0, y0)
        Pe = Point(x1, y1)

        # Anhängen der LineGeo Klasse für die Geometrie
        # Annexes to LineGeo class for geometry ???
        self.geo.append(LineGeo(Ps=Ps, Pe=Pe))

        # Länge entspricht der Länge des Kreises
        # Length corresponding to the length (circumference?) of the circle
        self.length = self.geo[-1].length

        # Neuen Startwert für die nächste Geometrie zurückgeben
        # New starting value for the next geometry
        caller.start = s
Beispiel #21
0
    def add_to_sweep_array(self, geos=[], closed=True):
        """
        This instance adds the given geometries to the sweep array. If there 
        are already some defined it will just continue to add them. This may be 
        used to get the intersection of two shapes
        @param: the geometries to be added
        @param: if these geometries are closed shape or not
        """

        sweep_array = []
        self.geos += geos

        for geo_nr in range(len(geos)):
            geo = geos[geo_nr]
            geo.iPoints = []
            y_val = (geo.BB.Ps.y + geo.BB.Pe.y) / 2

            geo.neighbors = []
            geo.nr = geo_nr
            geo.Point = Point(x=geo.BB.Ps.x, y=y_val)

            # Add the neighbors before the geometrie
            if geo_nr == 0 and closed:
                geo.neighbors.append(geos[geo_nr - 1])
            else:
                geo.neighbors.append(geos[geo_nr - 1])

            # Add the neighbors after the geometrie
            if geo_nr == len(geos) - 1 and closed:
                geo.neighbors.append(geos[0])
            else:
                geo.neighbors.append(geos[geo_nr + 1])

            y_val = (geo.BB.Ps.y + geo.BB.Pe.y) / 2
            sweep_array.append(
                SweepElement(Point=geo.Point, add=[geo], remove=[]))
            sweep_array.append(
                SweepElement(Point=Point(x=geo.BB.Pe.x, y=y_val),
                             add=[],
                             remove=[geo]))

        # logger.debug(sweep_array)
        sweep_array.sort(self.cmp_SweepElement)

        # Remove all Points which are there twice
        self.sweep_array = [sweep_array[0]]
        for ele_nr in range(1, len(sweep_array)):
            if abs(self.sweep_array[-1].Point.x -
                   sweep_array[ele_nr].Point.x) < eps:
                self.sweep_array[-1].add += sweep_array[ele_nr].add
                self.sweep_array[-1].remove += sweep_array[ele_nr].remove
            else:
                self.sweep_array.append(sweep_array[ele_nr])
Beispiel #22
0
 def __init__(self, gnWikipediaResult):
     lat = gnWikipediaResult['lat']
     lon = gnWikipediaResult['lng']
     # for storage, we remember both name and summary in the message variable
     message = "%s\n%s" % (gnWikipediaResult['title'], gnWikipediaResult['summary'])
     name = gnWikipediaResult["title"]
     Point.__init__(self, lat, lon,
                    elevation=gnWikipediaResult.get('elevation', None),
                    name=gnWikipediaResult['title'],
                    summary="%s..." % gnWikipediaResult['summary'][0:50],
                    message=gnWikipediaResult['summary']
     )
     self.result = gnWikipediaResult
Beispiel #23
0
 def __init__(self, lat, lon, name="", description="", phoneNumbers=None, urls=None, addressLines=None, emails=None):
     if not emails: emails = []
     if not addressLines: addressLines = []
     if not urls: urls = []
     if not phoneNumbers: phoneNumbers = []
     Point.__init__(self, lat, lon, message=name)
     self._name = name
     self.description = description
     self._message = None
     self._phoneNumbers = phoneNumbers
     self.urls = urls
     self._addressLines = addressLines
     self.emails = emails
Beispiel #24
0
    def makeShapes(self):
        self.entityRoot = EntityContent(nr=0, name='Entities', parent=None,
                                        p0=Point(self.cont_dx, self.cont_dy), pb=Point(),
                                        sca=[self.cont_scale, self.cont_scale, self.cont_scale], rot=self.cont_rotate)
        self.layerContents = Layers([])
        self.shapes = Shapes([])

        self.makeEntityShapes(self.entityRoot)

        for layerContent in self.layerContents:
            layerContent.overrideDefaults()
        self.layerContents.sort(key=lambda x: x.nr)
        self.newNumber = len(self.shapes)
Beispiel #25
0
    def calc_O1_O2_k(self, r1, r2, tan_a, theta):
        """
        calc_O1_O2_k()
        """
        # print("r1: %0.3f, r2: %0.3f, tan_a: %0.3f, theta: %0.3f" %(r1,r2,tan_a,theta))
        # print("N1: x: %0.3f, y: %0.3f" %(-sin(tan_a), cos(tan_a)))
        # print("V: x: %0.3f, y: %0.3f" %(-sin(theta+tan_a),cos(theta+tan_a)))

        O1 = Point(self.Ps.x - r1 * sin(tan_a), self.Ps.y + r1 * cos(tan_a))
        k = Point(self.Ps.x + r1 * (-sin(tan_a) + sin(theta + tan_a)),
                  self.Ps.y + r1 * (cos(tan_a) - cos(tan_a + theta)))
        O2 = Point(k.x + r2 * (-sin(theta + tan_a)),
                   k.y + r2 * (cos(theta + tan_a)))
        return O1, O2, k
Beispiel #26
0
    def calc_bounding_box(self):
        """
        Calculated the BoundingBox of the geometry and saves it into self.BB
        """

        Ps = Point(x=self.O.x - self.r, y=self.O.y - self.r)
        Pe = Point(x=self.O.x + self.r, y=self.O.y + self.r)

        # Do the calculation only for arcs have positiv extend => switch angles
        if self.ext >= 0:
            s_ang = self.s_ang
            e_ang = self.e_ang
        elif self.ext < 0:
            s_ang = self.e_ang
            e_ang = self.s_ang

        # If the positive X Axis is crossed
        if not (self.wrap(s_ang, 0) >= self.wrap(e_ang, 1)):
            Pe.x = max(self.Ps.x, self.Pe.x)

        # If the positive Y Axis is crossed
        if not (self.wrap(s_ang - pi / 2, 0) >= self.wrap(e_ang - pi / 2, 1)):
            Pe.y = max(self.Ps.y, self.Pe.y)

        # If the negative X Axis is crossed
        if not (self.wrap(s_ang - pi, 0) >= self.wrap(e_ang - pi, 1)):
            Ps.x = min(self.Ps.x, self.Pe.x)

        # If the negative Y is crossed
        if not (self.wrap(s_ang - 1.5 * pi, 0) >= self.wrap(
                e_ang - 1.5 * pi, 1)):
            Ps.y = min(self.Ps.y, self.Pe.y)

        self.BB = BoundingBox(Ps=Ps, Pe=Pe)
Beispiel #27
0
    def __init__(self):
        QGraphicsScene.__init__(self)

        self.shapes = []
        self.wpzero = None
        self.routearrows = []
        self.routetext = []
        self.expprv = None
        self.expcol = None
        self.expnr = 0

        self.showDisabledPaths = False

        self.topLeft = Point()
        self.bottomRight = Point()
Beispiel #28
0
    def __init__(self):
        QGraphicsScene.__init__(self)

        self.shapes = []
        self.wpzero = None
        self.routearrows = []
        self.routetext = []
        self.expprv = None
        self.expcol = None
        self.expnr = 0

        self.showDisabledPaths = False

        self.topLeft = Point()
        self.bottomRight = Point()
Beispiel #29
0
 def __init__(self, gnWikipediaResult):
     lat = gnWikipediaResult['lat']
     lon = gnWikipediaResult['lng']
     # for storage, we remember both name and summary in the message variable
     message = "%s\n%s" % (gnWikipediaResult['title'],
                           gnWikipediaResult['summary'])
     name = gnWikipediaResult["title"]
     Point.__init__(self,
                    lat,
                    lon,
                    elevation=gnWikipediaResult.get('elevation', None),
                    name=gnWikipediaResult['title'],
                    summary="%s..." % gnWikipediaResult['summary'][0:50],
                    message=gnWikipediaResult['summary'])
     self.result = gnWikipediaResult
Beispiel #30
0
def locateCurrentPosition(controller=None):
    """Try to locate current position and return it when done or time out"""
    result = None
    sleepTime = 0.5  # in seconds
    pos = modrana.get('pos', None)
    fix = modrana.get('fix', 1)
    # check if GPS usage is explicitly disabled in modRana
    gpsEnabled = modrana.get('GPSEnabled')
    if gpsEnabled == False:
        if pos:
            modrana.notify("GPS OFF, using last known position", 5000)
            return Point(*pos)
        else:
            modrana.notify("GPS OFF, no last known position", 5000)
            return None

    if fix > 1 and pos:
        return Point(*pos)  # fix found, return it at once

    # check if GPS hardware has been enabled
    location = modrana.m.get("location")
    if not location.enabled:
        # location usage has not be disabled but location
        # has not been started, so start location
        location.start_location()

    # wait for the fix
    startTimestamp = time.time()
    elapsed = 0
    if controller:
        controller.status = "GPS fix in progress"
    while elapsed < constants.LOCATION_TIMEOUT:
        pos = modrana.get('pos', None)
        fix = modrana.get('fix', 1)
        if fix > 1 and pos:
            break
        time.sleep(sleepTime)
        elapsed = time.time() - startTimestamp
    if fix > 1 and pos:  # got GPS fix ?
        return Point(*pos)
    else:  # no GPS lock
        pos = modrana.get("pos")
        if pos:
            modrana.notify("no fix, using last known position", 5000)
            return Point(*pos)
        else:
            modrana.notify("failed to get GPS fix", 5000)
            return None
Beispiel #31
0
    def mouseMoveEvent(self, event):
        """
        MouseMoveEvent of the Graphiscview. May also be used for the Statusbar.
        @purpose: Get the MouseMoveEvent and use it for the Rubberband Selection
        @param event: Event Parameters passed to function
        """
        if self.mppos is not None:
            Point = event.pos() - self.mppos
            if Point.manhattanLength() > 3:
                # print 'the mouse has moved more than 3 pixels since the oldPosition'
                # print "Mouse Pointer is currently hovering at: ", event.pos()
                rect = QtCore.QRect(self.mppos, event.pos())
                '''
                The following is needed because of PyQt5 doesn't like to switch from sign
                 it will keep displaying last rectangle, i.e. you can end up will multiple rectangles
                '''
                if self.prvRectRubberBand.width() > 0 and not rect.width() > 0 or rect.width() == 0 or\
                   self.prvRectRubberBand.height() > 0 and not rect.height() > 0 or rect.height() == 0:
                    self.rubberBand.hide()
                self.rubberBand.setGeometry(rect.normalized())
                self.rubberBand.show()
                self.prvRectRubberBand = rect

        scpoint = self.mapToScene(event.pos())

        # self.setStatusTip('X: %3.1f; Y: %3.1f' % (scpoint.x(), -scpoint.y()))
        # works not as supposed to
        self.setToolTip('X: %3.1f; Y: %3.1f' % (scpoint.x(), -scpoint.y()))

        super(MyGraphicsView, self).mouseMoveEvent(event)
Beispiel #32
0
 def __init__(self, gnWikipediaResult):
     lat = gnWikipediaResult["lat"]
     lon = gnWikipediaResult["lng"]
     # for storage, we remember both name and summary in the message variable
     message = "%s\n%s" % (gnWikipediaResult["title"], gnWikipediaResult["summary"])
     name = gnWikipediaResult["title"]
     Point.__init__(
         self,
         lat,
         lon,
         elevation=gnWikipediaResult.get("elevation", None),
         name=gnWikipediaResult["title"],
         summary="%s..." % gnWikipediaResult["summary"][0:50],
         message=gnWikipediaResult["summary"],
     )
     self.result = gnWikipediaResult
Beispiel #33
0
    def mouseMoveEvent(self, event):
        """
        MouseMoveEvent of the Graphiscview. May also be used for the Statusbar.
        @purpose: Get the MouseMoveEvent and use it for the Rubberband Selection
        @param event: Event Parameters passed to function
        """
        if self.mppos is not None:
            Point = event.pos() - self.mppos
            if Point.manhattanLength() > 3:
                # print 'the mouse has moved more than 3 pixels since the oldPosition'
                # print "Mouse Pointer is currently hovering at: ", event.pos()
                rect = QtCore.QRect(self.mppos, event.pos())
                '''
                The following is needed because of PyQt5 doesn't like to switch from sign
                 it will keep displaying last rectangle, i.e. you can end up will multiple rectangles
                '''
                if self.prvRectRubberBand.width() > 0 and not rect.width() > 0 or rect.width() == 0 or\
                   self.prvRectRubberBand.height() > 0 and not rect.height() > 0 or rect.height() == 0:
                    self.rubberBand.hide()
                self.rubberBand.setGeometry(rect.normalized())
                self.rubberBand.show()
                self.prvRectRubberBand = rect

        scpoint = self.mapToScene(event.pos())

        # self.setStatusTip('X: %3.1f; Y: %3.1f' % (scpoint.x(), -scpoint.y()))
        # works not as supposed to
        self.setToolTip('X: %3.1f; Y: %3.1f' %(scpoint.x(), -scpoint.y()))

        super(MyGraphicsView, self).mouseMoveEvent(event)
Beispiel #34
0
    def __init__(self,
                 startp=Point(),
                 endp=None,
                 length=60.0,
                 angle=50.0,
                 color=QtCore.Qt.red,
                 pencolor=QtCore.Qt.green,
                 startarrow=True):
        """
        Initialisation of the class.
        """
        self.sc = None
        super(Arrow, self).__init__()

        self.startp = QtCore.QPointF(startp.x, -startp.y)
        self.endp = endp

        self.length = length
        self.angle = angle
        self.startarrow = startarrow
        self.allwaysshow = False

        self.arrowHead = QPolygonF()
        self.setFlag(QGraphicsItem.ItemIsSelectable, False)
        self.myColor = color
        self.pen = QPen(pencolor, 1, QtCore.Qt.SolidLine)
        self.pen.setCosmetic(True)
        self.arrowSize = 8.0
Beispiel #35
0
 def nodes(self):
     if self._nodes is None:
         node_points = []
         for node in self._result_dict["nodes"]:
             node_points.append(Point(lat=node[0], lon=node[1]))
             self._nodes = node_points
     return self._nodes
Beispiel #36
0
    def analyse_and_opt(self):
        """
        analyse_and_opt()
        """
        summe = 0

        # Richtung in welcher der Anfang liegen soll (unten links)
        # Direction of the top (lower left) ???
        Popt = Point(-1e3, -1e6)

        # Calculation of the alignment after Gaussian-Elling
        # Positive value means CW, negative value indicates CCW
        # closed polygon
        for Line in self.geo:
            summe += Line.Ps.x * Line.Pe.y - Line.Pe.x * Line.Ps.y

        if summe > 0.0:
            self.reverse()

        # Suchen des kleinsten Startpunkts von unten Links X zuerst (Muss neue Schleife sein!)
        # Find the smallest starting point from bottom left X (Must be new loop!)
        min_distance = self.geo[0].Ps.distance(Popt)
        min_geo_nr = 0
        for geo_nr in range(1, len(self.geo)):
            if self.geo[geo_nr].Ps.distance(Popt) < min_distance:
                min_distance = self.geo[geo_nr].Ps.distance(Popt)
                min_geo_nr = geo_nr

        # Kontur so anordnen das neuer Startpunkt am Anfang liegt
        # Order Contour so the new starting point is at the beginning
        self.geo = self.geo[min_geo_nr:len(self.geo)] + self.geo[0:min_geo_nr]
    def calc_curve(self, n=0, cpts_nr=20):
        """
        Berechnen von eine Anzahl gleichm�ssig verteilter Punkte bis zur n-ten Ableitung
        """

        # Anfangswerte f�r Step und u
        u = 0
        step = float(self.Knots[-1]) / (cpts_nr - 1)
        Points = []

        # Wenn die erste Ableitung oder h�her errechnet wird die ersten
        # Ableitung in dem tan als Winkel in rad gespeichert
        tang = []

        while u <= self.Knots[-1]:
            CK = self.bspline_ders_evaluate(n=n, u=u)

            # Den Punkt in einem Punkt List abspeichern
            Points.append(Point(x=CK[0][0], y=CK[0][1]))

            # F�r die erste Ableitung wird den Winkel der tangente errechnet
            if n >= 1:
                tang.append(atan2(CK[1][1], CK[1][0]))
            u += step

        return Points, tang
Beispiel #38
0
    def Read(self, caller):
        """
        Read()
        """
        # Assign short name
        lp = caller.line_pairs
        e = lp.index_code(0, caller.start + 1)

        # Assign layer
        s = lp.index_code(8, caller.start + 1)
        self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value)

        # X Value
        s = lp.index_code(10, s + 1)
        x0 = float(lp.line_pair[s].value)

        # Y Value
        s = lp.index_code(20, s + 1)
        y0 = float(lp.line_pair[s].value)

        Ps = Point(x0, y0)

        self.geo.append(HoleGeo(Ps))
        # self.geo.append(LineGeo(Ps=Point(0,0), Pe=P))

        # Neuen Startwert für die nächste Geometrie zurückgeben
        # New starting value for the next geometry
        caller.start = s
Beispiel #39
0
 def contains_point(self, point):
     """
     Method to determine the minimal distance from the point to the shape
     @param point: a QPointF
     @return: minimal distance
     """
     min_distance = float(0x7fffffff)
     ref_point = Point(point.x(), point.y())
     t = 0.0
     while t < 1.0:
         per_point = self.path.pointAtPercent(t)
         spline_point = Point(per_point.x(), per_point.y())
         distance = ref_point.distance(spline_point)
         if distance < min_distance:
             min_distance = distance
         t += 0.01
     return min_distance
Beispiel #40
0
 def __init__(self, lat, lon, name="", phoneNumbers=None,
              urls=None, addressLines=None, emails=None, openingHours=None,
              priceLevel=None, rating=None):
     if not emails: emails = []
     if not addressLines: addressLines = []
     if not urls: urls = []
     if not phoneNumbers: phoneNumbers = []
     if not openingHours: openingHours = {}
     Point.__init__(self, lat, lon, name=name)
     self._message_loaded = False
     self._phoneNumbers = phoneNumbers
     self._urls = urls
     self._addressLines = addressLines
     self._emails = emails
     self._openingHours = openingHours
     self._priceLevel = priceLevel
     self._rating = rating
Beispiel #41
0
 def __init__(self, lat, lon, name="", description="", phoneNumbers=None,
              urls=None, addressLines=None, emails=None, openingHours=None,
              priceLevel=None, rating=None):
     if not emails: emails = []
     if not addressLines: addressLines = []
     if not urls: urls = []
     if not phoneNumbers: phoneNumbers = []
     if not openingHours: openingHours = {}
     Point.__init__(self, lat, lon, message=name)
     self._name = name
     self.description = description
     self._message = None
     self._phoneNumbers = phoneNumbers
     self.urls = urls
     self._addressLines = addressLines
     self.emails = emails
     self.openingHours = openingHours
     self._priceLevel = priceLevel
     self._rating = rating
Beispiel #42
0
    def resetAll(self):
        self.gl.glDeleteLists(1, self.orientation)  # the orientation arrows are currently generated last
        self.shapes = Shapes([])
        self.wpZero = 0
        self.orientation = 0
        self.delete_opt_paths()

        self.posX = 0.0
        self.posY = 0.0
        self.posZ = 0.0
        self.rotX = 0.0
        self.rotY = 0.0
        self.rotZ = 0.0
        self.scale = 1.0

        self.topLeft = Point()
        self.bottomRight = Point()

        self.update()
Beispiel #43
0
 def full_point_test(self):
     """Check if a point with all constructor options is correctly created"""
     point = Point(1.0, 2.0, elevation=100.5, name="foo name",
                   summary="bar summary", message="baz message")
     self.assertEqual(point.lat, 1.0)
     self.assertEqual(point.lon, 2.0)
     self.assertEqual(point.elevation, 100.5)
     # test name, etc.
     self.assertEqual(point.name, "foo name")
     self.assertEqual(point.summary, "bar summary")
     self.assertEqual(point.description, "baz message")
     # test the tuple getters/setters
     self.assertEqual(point.getLL(), (1.0, 2.0))
     point.setLL(3.0, 4.0)
     self.assertEqual(point.getLL(), (3.0, 4.0))
     self.assertEqual(point.getLLE(), (3.0, 4.0, 100.5))
     point.setLLE(5.0, 6.0, 200.5)
     self.assertEqual(point.getLLE(), (5.0, 6.0, 200.5))
     self.assertEqual(point.getLLEM(), (5.0, 6.0, 200.5, "baz message"))
Beispiel #44
0
    def resetAll(self):
        # the wpzero is currently generated "last"
        if self.wpZero > 0:
            GL.glDeleteLists(self.orientation + 1, self.wpZero - self.orientation)
        self.shapes = Shapes([])
        self.wpZero = 0
        self.delete_opt_paths()

        self.posX = 0.0
        self.posY = 0.0
        self.posZ = 0.0
        self.rotX = 0.0
        self.rotY = 0.0
        self.rotZ = 0.0
        self.scale = 1.0

        self.topLeft = Point()
        self.bottomRight = Point()

        self.update()
Beispiel #45
0
    def calc_bounding_box(self):
        """
        Calculated the BoundingBox of the geometry and saves it into self.BB
        """

        Ps = Point(x=self.O.x - self.r, y=self.O.y - self.r)
        Pe = Point(x=self.O.x + self.r, y=self.O.y + self.r)

        # Do the calculation only for arcs have positiv extend => switch angles
        if self.ext >= 0:
            s_ang = self.s_ang
            e_ang = self.e_ang
        elif self.ext < 0:
            s_ang = self.e_ang
            e_ang = self.s_ang

        # If the positive X Axis is crossed
        if not(self.wrap(s_ang, 0) >= self.wrap(e_ang, 1)):
            Pe.x = max(self.Ps.x, self.Pe.x)

        # If the positive Y Axis is crossed
        if not(self.wrap(s_ang - pi / 2, 0) >= self.wrap(e_ang - pi / 2, 1)):
            Pe.y = max(self.Ps.y, self.Pe.y)

        # If the negative X Axis is crossed
        if not(self.wrap(s_ang - pi, 0) >= self.wrap(e_ang - pi, 1)):
            Ps.x = min(self.Ps.x, self.Pe.x)

        # If the negative Y is crossed
        if not(self.wrap(s_ang - 1.5 * pi, 0) >=
                self.wrap(e_ang - 1.5 * pi, 1)):
            Ps.y = min(self.Ps.y, self.Pe.y)

        self.BB = BoundingBox(Ps=Ps, Pe=Pe)
Beispiel #46
0
    def bulge2arc(self, Ps, Pe, bulge):
        """
        bulge2arc()
        """
        c = (1 / bulge - bulge) / 2

        # Calculate the centre point (Micke's formula!)
        O = Point((Ps.x + Pe.x - (Pe.y - Ps.y) * c) / 2,
                  (Ps.y + Pe.y + (Pe.x - Ps.x) * c) / 2)

        # Radius = Distance between the centre and Ps
        r = O.distance(Ps)

        # Check if they are equal (fits ...)
        # r=O.distance(Pe)

        # Unterscheidung f�r den �ffnungswinkel.
        # Distinction for the opening angle. ???
        if bulge > 0:
            return ArcGeo(Ps=Ps, Pe=Pe, O=O, r=r)
        else:
            arc = ArcGeo(Ps=Pe, Pe=Ps, O=O, r=r)
            arc.reverse()
            return arc
Beispiel #47
0
 def __init__(self, lat, lon, elevation=None, message=None, SSMLMessage=None):
     Point.__init__(self, lat, lon, elevation=elevation, message=message)
     self.currentDistance = None # in meters
     self.distanceFromStart = None # in meters
     self.visited = False
     self.SSMLMessage = SSMLMessage
Beispiel #48
0
class MyGraphicsScene(QGraphicsScene):
    """
    This is the Canvas used to print the graphical interface of dxf2gcode.
    The Scene is rendered into the previously defined mygraphicsView class.
    All performed plotting functions should be defined here.
    @sideeffect: None
    """
    def __init__(self):
        QGraphicsScene.__init__(self)

        self.shapes = []
        self.wpzero = None
        self.routearrows = []
        self.routetext = []
        self.expprv = None
        self.expcol = None
        self.expnr = 0

        self.showDisabledPaths = False

        self.topLeft = Point()
        self.bottomRight = Point()

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return text_type(QtCore.QCoreApplication.translate('MyGraphicsScene',
                                                           string_to_translate))

    def plotAll(self, shapes):
        """
        Instance is called by the Main Window after the defined file is loaded.
        It generates all ploting functionality. The parameters are generally
        used to scale or offset the base geometry (by Menu in GUI).
        """
        for shape in shapes:
            self.paint_shape(shape)
            self.addItem(shape)
            self.shapes.append(shape)
        self.draw_wp_zero()
        self.update()

    def repaint_shape(self, shape):
        # setParentItem(None) might let it crash, hence we rely on the garbage collector
        shape.stmove.hide()
        shape.starrow.hide()
        shape.enarrow.hide()
        del shape.stmove
        del shape.starrow
        del shape.enarrow
        self.paint_shape(shape)
        if not shape.isSelected():
            shape.stmove.hide()
            shape.starrow.hide()
            shape.enarrow.hide()

    def paint_shape(self, shape):
        """
        Create all plotting related parts of one shape.
        @param shape: The shape to be plotted.
        """
        start, start_ang = shape.get_start_end_points(True, True)
        shape.path = QPainterPath()
        shape.path.moveTo(start.x, -start.y)
        drawHorLine = lambda caller, start, end: shape.path.lineTo(end.x, -end.y)
        drawVerLine = lambda caller, start: None  # Not used in 2D mode
        shape.make_path(drawHorLine, drawVerLine)

        self.topLeft.detTopLeft(shape.topLeft)
        self.bottomRight.detBottomRight(shape.bottomRight)

        shape.stmove = self.createstmove(shape)
        shape.starrow = self.createstarrow(shape)
        shape.enarrow = self.createenarrow(shape)
        shape.stmove.setParentItem(shape)
        shape.starrow.setParentItem(shape)
        shape.enarrow.setParentItem(shape)

    def draw_wp_zero(self):
        """
        This function is called while the drawing of all items is done. It plots
        the WPZero to the Point x=0 and y=0. This item will be enabled or
        disabled to be shown or not.
        """
        self.wpzero = WpZero(QtCore.QPointF(0, 0))
        self.addItem(self.wpzero)

    def createstarrow(self, shape):
        """
        This function creates the Arrows at the end point of a shape when the
        shape is selected.
        @param shape: The shape for which the Arrow shall be created.
        """

        length = 20
        start, start_ang = shape.get_start_end_points_physical(True, True)
        arrow = Arrow(startp=start,
                      length=length,
                      angle=start_ang,
                      color=QColor(50, 200, 255),
                      pencolor=QColor(50, 100, 255))
        return arrow

    def createenarrow(self, shape):
        """
        This function creates the Arrows at the end point of a shape when the
        shape is selected.
        @param shape: The shape for which the Arrow shall be created.
        """
        length = 20
        end, end_ang = shape.get_start_end_points_physical(False, True)
        arrow = Arrow(startp=end,
                      length=length,
                      angle=end_ang,
                      color=QColor(0, 245, 100),
                      pencolor=QColor(0, 180, 50),
                      startarrow=False)
        return arrow

    def createstmove(self, shape):
        """
        This function creates the Additional Start and End Moves in the plot
        window when the shape is selected
        @param shape: The shape for which the Move shall be created.
        """
        stmove = StMoveGUI(shape)
        return stmove

    def delete_opt_paths(self):
        """
        This function deletes all the plotted export routes.
        """
        # removeItem might let it crash, hence we rely on the garbage collector
        while self.routearrows:
            item = self.routearrows.pop()
            item.hide()
            del item

        while self.routetext:
            item = self.routetext.pop()
            item.hide()
            del item

    def addexproutest(self):
        self.expprv = Point(g.config.vars.Plane_Coordinates['axis1_start_end'],
                            g.config.vars.Plane_Coordinates['axis2_start_end'])
        self.expcol = QtCore.Qt.darkRed

    def addexproute(self, exp_order, layer_nr):
        """
        This function initialises the Arrows of the export route order and its numbers.
        """
        for shape_nr in range(len(exp_order)):
            shape = self.shapes[exp_order[shape_nr]]
            st = self.expprv
            en, self.expprv = shape.get_start_end_points_physical()
            self.routearrows.append(Arrow(startp=en,
                                          endp=st,
                                          color=self.expcol,
                                          pencolor=self.expcol))

            self.expcol = QtCore.Qt.darkGray

            self.routetext.append(RouteText(text=("%s,%s" % (layer_nr, shape_nr+1)),
                                            startp=en))
            # self.routetext[-1].ItemIgnoresTransformations

            self.addItem(self.routearrows[-1])
            self.addItem(self.routetext[-1])

    def addexprouteen(self):
        st = self.expprv
        en = Point(g.config.vars.Plane_Coordinates['axis1_start_end'],
                   g.config.vars.Plane_Coordinates['axis2_start_end'])
        self.expcol = QtCore.Qt.darkRed

        self.routearrows.append(Arrow(startp=en,
                                      endp=st,
                                      color=self.expcol,
                                      pencolor=self.expcol))

        self.addItem(self.routearrows[-1])

    def setShowDisabledPaths(self, flag):
        """
        This function is called by the Main Menu and is passed from Main to
        MyGraphicsView to the Scene. It performs the showing or hiding
        of enabled/disabled shapes.

        @param flag: This flag is true if hidden paths shall be shown
        """
        self.showDisabledPaths = flag

        for shape in self.shapes:
            if flag and shape.isDisabled():
                shape.show()
            elif not flag and shape.isDisabled():
                shape.hide()
Beispiel #49
0
class GLWidget(CanvasBase):
    CAM_LEFT_X = -0.5
    CAM_RIGHT_X = 0.5
    CAM_BOTTOM_Y = 0.5
    CAM_TOP_Y = -0.5
    CAM_NEAR_Z = -14.0
    CAM_FAR_Z = 14.0

    COLOR_BACKGROUND = QColor.fromHsl(160, 0, 255, 255)
    COLOR_NORMAL = QColor.fromCmykF(1.0, 0.5, 0.0, 0.0, 1.0)
    COLOR_SELECT = QColor.fromCmykF(0.0, 1.0, 0.9, 0.0, 1.0)
    COLOR_NORMAL_DISABLED = QColor.fromCmykF(1.0, 0.5, 0.0, 0.0, 0.25)
    COLOR_SELECT_DISABLED = QColor.fromCmykF(0.0, 1.0, 0.9, 0.0, 0.25)
    COLOR_ENTRY_ARROW = QColor.fromRgbF(0.0, 0.0, 1.0, 1.0)
    COLOR_EXIT_ARROW = QColor.fromRgbF(0.0, 1.0, 0.0, 1.0)
    COLOR_ROUTE = QColor.fromRgbF(0.5, 0.0, 0.0, 1.0)
    COLOR_STMOVE = QColor.fromRgbF(0.5, 0.0, 0.25, 1.0)
    COLOR_BREAK = QColor.fromRgbF(1.0, 0.0, 1.0, 0.7)
    COLOR_LEFT = QColor.fromHsl(134, 240, 130, 255)
    COLOR_RIGHT = QColor.fromHsl(186, 240, 130, 255)

    def __init__(self, parent=None):
        super(GLWidget, self).__init__(parent)

        self.shapes = Shapes([])
        self.orientation = 0
        self.wpZero = 0
        self.routearrows = []
        self.expprv = None

        self.isPanning = False
        self.isRotating = False
        self.isMultiSelect = False
        self._lastPos = QPoint()

        self.posX = 0.0
        self.posY = 0.0
        self.posZ = 0.0
        self.rotX = 0.0
        self.rotY = 0.0
        self.rotZ = 0.0
        self.scale = 1.0
        self.scaleCorr = 1.0

        self.showPathDirections = False
        self.showDisabledPaths = False

        self.topLeft = Point()
        self.bottomRight = Point()

        self.tol = 0

    def resetAll(self):
        self.gl.glDeleteLists(1, self.orientation)  # the orientation arrows are currently generated last
        self.shapes = Shapes([])
        self.wpZero = 0
        self.orientation = 0
        self.delete_opt_paths()

        self.posX = 0.0
        self.posY = 0.0
        self.posZ = 0.0
        self.rotX = 0.0
        self.rotY = 0.0
        self.rotZ = 0.0
        self.scale = 1.0

        self.topLeft = Point()
        self.bottomRight = Point()

        self.update()

    def delete_opt_paths(self):
        if len(self.routearrows) > 0:
            self.gl.glDeleteLists(self.routearrows[0][2], len(self.routearrows))
            self.routearrows = []

    def addexproutest(self):
        self.expprv = Point3D(g.config.vars.Plane_Coordinates['axis1_start_end'],
                              g.config.vars.Plane_Coordinates['axis2_start_end'],
                              0)

    def addexproute(self, exp_order, layer_nr):
        """
        This function initialises the Arrows of the export route order and its numbers.
        """
        for shape_nr in range(len(exp_order)):
            shape = self.shapes[exp_order[shape_nr]]
            st = self.expprv
            en, self.expprv = shape.get_start_end_points_physical()
            en = en.to3D(shape.axis3_start_mill_depth)
            self.expprv = self.expprv.to3D(shape.axis3_mill_depth)

            self.routearrows.append([st, en, 0])

            # TODO self.routetext.append(RouteText(text=("%s,%s" % (layer_nr, shape_nr+1)), startp=en))

    def addexprouteen(self):
        st = self.expprv
        en = Point3D(g.config.vars.Plane_Coordinates['axis1_start_end'],
                     g.config.vars.Plane_Coordinates['axis2_start_end'],
                     0)

        self.routearrows.append([st, en, 0])
        for route in self.routearrows:
            route[2] = self.makeRouteArrowHead(route[0], route[1])

    def contextMenuEvent(self, event):
        if not self.isRotating:
            clicked, offset, _ = self.getClickedDetails(event)
            MyDropDownMenu(self, event.globalPos(), clicked, offset)

    def setXRotation(self, angle):
        self.rotX = self.normalizeAngle(angle)

    def setYRotation(self, angle):
        self.rotY = self.normalizeAngle(angle)

    def setZRotation(self, angle):
        self.rotZ = self.normalizeAngle(angle)

    def normalizeAngle(self, angle):
        return (angle - 180) % -360 + 180

    def mousePressEvent(self, event):
        if self.isPanning or self.isRotating:
            self.setCursor(Qt.ClosedHandCursor)
        elif event.button() == Qt.LeftButton:
            clicked, offset, tol = self.getClickedDetails(event)
            xyForZ = {}
            for shape in self.shapes:
                hit = False
                z = shape.axis3_start_mill_depth
                if z not in xyForZ:
                    xyForZ[z] = self.determineSelectedPosition(clicked, z, offset)
                hit |= shape.isHit(xyForZ[z], tol)

                if not hit:
                    z = shape.axis3_mill_depth
                    if z not in xyForZ:
                        xyForZ[z] = self.determineSelectedPosition(clicked, z, offset)
                    hit |= shape.isHit(xyForZ[z], tol)

                if self.isMultiSelect and shape.selected:
                    hit = not hit

                if hit != shape.selected:
                    g.window.TreeHandler.updateShapeSelection(shape, hit)

                shape.selected = hit

            self.update()
        self._lastPos = event.pos()

    def getClickedDetails(self, event):
        min_side = min(self.frameSize().width(), self.frameSize().height())
        clicked = Point((event.pos().x() - self.frameSize().width() / 2),
                        (event.pos().y() - self.frameSize().height() / 2)) / min_side / self.scale
        offset = Point3D(-self.posX, -self.posY, -self.posZ) / self.scale
        tol = 4 * self.scaleCorr / min_side / self.scale
        return clicked, offset, tol

    def determineSelectedPosition(self, clicked, forZ, offset):
        angleX = -radians(self.rotX)
        angleY = -radians(self.rotY)

        zv = forZ - offset.z
        clickedZ = ((zv + clicked.x * sin(angleY)) / cos(angleY) - clicked.y * sin(angleX)) / cos(angleX)
        sx, sy, sz = self.deRotate(clicked.x, clicked.y, clickedZ)
        return Point(sx + offset.x, - sy - offset.y)  #, sz + offset.z

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton or event.button() == Qt.RightButton:
            if self.isPanning:
                self.setCursor(Qt.OpenHandCursor)
            elif self.isRotating:
                self.setCursor(Qt.PointingHandCursor)

    def mouseMoveEvent(self, event):
        dx = event.pos().x() - self._lastPos.x()
        dy = event.pos().y() - self._lastPos.y()

        if self.isRotating:
            if event.buttons() == Qt.LeftButton:
                self.setXRotation(self.rotX - dy / 2)
                self.setYRotation(self.rotY + dx / 2)
            elif event.buttons() == Qt.RightButton:
                self.setXRotation(self.rotX - dy / 2)
                self.setZRotation(self.rotZ + dx / 2)
        elif self.isPanning:
            if event.buttons() == Qt.LeftButton:
                min_side = min(self.frameSize().width(), self.frameSize().height())
                dx, dy, dz = self.deRotate(dx, dy, 0)
                self.posX += dx / min_side
                self.posY += dy / min_side
                self.posZ += dz / min_side

        self._lastPos = event.pos()
        self.update()

    def wheelEvent(self, event):
        min_side = min(self.frameSize().width(), self.frameSize().height())
        x = (event.pos().x() - self.frameSize().width() / 2) / min_side
        y = (event.pos().y() - self.frameSize().height() / 2) / min_side
        s = 1.001 ** event.angleDelta().y()

        x, y, z = self.deRotate(x, y, 0)
        self.posX = (self.posX - x) * s + x
        self.posY = (self.posY - y) * s + y
        self.posZ = (self.posZ - z) * s + z
        self.scale *= s

        self.update()

    def rotate(self, x, y, z):
        angleZ = radians(self.rotZ)
        x, y, z = x*cos(angleZ) - y*sin(angleZ), x*sin(angleZ) + y*cos(angleZ), z
        angleY = radians(self.rotY)
        x, y, z = x*cos(angleY) + z*sin(angleY), y, -x*sin(angleY) + z*cos(angleY)
        angleX = radians(self.rotX)
        return x, y*cos(angleX) - z*sin(angleX), y*sin(angleX) + z*cos(angleX)

    def deRotate(self, x, y, z):
        angleX = -radians(self.rotX)
        x, y, z = x, y*cos(angleX) - z*sin(angleX), y*sin(angleX) + z*cos(angleX)
        angleY = -radians(self.rotY)
        x, y, z = x*cos(angleY) + z*sin(angleY), y, -x*sin(angleY) + z*cos(angleY)
        angleZ = -radians(self.rotZ)
        return x*cos(angleZ) - y*sin(angleZ), x*sin(angleZ) + y*cos(angleZ), z

    def getRotationVectors(self, orgRefVector, toRefVector):
        """
        Generate a rotation matrix such that toRefVector = matrix * orgRefVector
        @param orgRefVector: A 3D unit vector
        @param toRefVector: A 3D unit vector
        @return: 3 vectors such that matrix = [vx; vy; vz]
        """
        # based on:
        # http://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d

        if orgRefVector == toRefVector:
            return Point3D(1, 0, 0), Point3D(0, 1, 0), Point3D(0, 0, 1)

        v = orgRefVector.cross_product(toRefVector)
        mn = (1 - orgRefVector * toRefVector) / v.length_squared()

        vx = Point3D(1, -v.z, v.y) + mn * Point3D(-v.y**2 - v.z**2, v.x * v.y, v.x * v.z)
        vy = Point3D(v.z, 1, -v.x) + mn * Point3D(v.x * v.y, -v.x**2 - v.z**2, v.y * v.z)
        vz = Point3D(-v.y, v.x, 1) + mn * Point3D(v.x * v.z, v.y * v.z, -v.x**2 - v.y**2)

        return vx, vy, vz

    def initializeGL(self):
        version = QOpenGLVersionProfile()
        version.setVersion(2, 0)
        self.gl = self.context().versionFunctions(version)
        self.gl.initializeOpenGLFunctions()

        self.setClearColor(GLWidget.COLOR_BACKGROUND)

        # self.gl.glPolygonMode(self.gl.GL_FRONT_AND_BACK, self.gl.GL_LINE )
        self.gl.glShadeModel(self.gl.GL_SMOOTH)
        self.gl.glEnable(self.gl.GL_DEPTH_TEST)
        self.gl.glEnable(self.gl.GL_CULL_FACE)
        # self.gl.glEnable(self.gl.GL_LIGHTING)
        # self.gl.glEnable(self.gl.GL_LIGHT0)
        self.gl.glEnable(self.gl.GL_MULTISAMPLE)
        self.gl.glEnable(self.gl.GL_BLEND)
        self.gl.glBlendFunc(self.gl.GL_SRC_ALPHA, self.gl.GL_ONE_MINUS_SRC_ALPHA)
        # self.gl.glLightfv(self.gl.GL_LIGHT0, self.gl.GL_POSITION, (0.5, 5.0, 7.0, 1.0))
        # self.gl.glEnable(self.gl.GL_NORMALIZE)

    def paintGL(self):
        # The last transformation you specify takes place first.
        self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT | self.gl.GL_DEPTH_BUFFER_BIT)
        self.gl.glLoadIdentity()
        self.gl.glRotatef(self.rotX, 1.0, 0.0, 0.0)
        self.gl.glRotatef(self.rotY, 0.0, 1.0, 0.0)
        self.gl.glRotatef(self.rotZ, 0.0, 0.0, 1.0)
        self.gl.glTranslatef(self.posX, self.posY, self.posZ)
        self.gl.glScalef(self.scale, self.scale, self.scale)
        for shape in self.shapes.selected_iter():
            if not shape.disabled:
                self.setColor(GLWidget.COLOR_STMOVE)
                self.gl.glCallList(shape.drawStMove)
                self.setColor(GLWidget.COLOR_SELECT)
                self.gl.glCallList(shape.drawObject)
            elif self.showDisabledPaths:
                self.setColor(GLWidget.COLOR_SELECT_DISABLED)
                self.gl.glCallList(shape.drawObject)
        for shape in self.shapes.not_selected_iter():
            if not shape.disabled:
                if shape.parentLayer.isBreakLayer():
                    self.setColor(GLWidget.COLOR_BREAK)
                elif shape.cut_cor == 41:
                    self.setColor(GLWidget.COLOR_LEFT)
                elif shape.cut_cor == 42:
                    self.setColor(GLWidget.COLOR_RIGHT)
                else:
                    self.setColor(GLWidget.COLOR_NORMAL)
                self.gl.glCallList(shape.drawObject)
                if self.showPathDirections:
                    self.setColor(GLWidget.COLOR_STMOVE)
                    self.gl.glCallList(shape.drawStMove)
            elif self.showDisabledPaths:
                self.setColor(GLWidget.COLOR_NORMAL_DISABLED)
                self.gl.glCallList(shape.drawObject)

        # optimization route arrows
        self.setColor(GLWidget.COLOR_ROUTE)
        self.gl.glBegin(self.gl.GL_LINES)
        for route in self.routearrows:
            start = route[0]
            end = route[1]
            self.gl.glVertex3f(start.x, -start.y, start.z)
            self.gl.glVertex3f(end.x, -end.y, end.z)
        self.gl.glEnd()

        self.gl.glScalef(self.scaleCorr / self.scale, self.scaleCorr / self.scale, self.scaleCorr / self.scale)
        scaleArrow = self.scale / self.scaleCorr
        for route in self.routearrows:
            end = scaleArrow * route[1]
            self.gl.glTranslatef(end.x, -end.y, end.z)
            self.gl.glCallList(route[2])
            self.gl.glTranslatef(-end.x, end.y, -end.z)

        # direction arrows
        for shape in self.shapes:
            if shape.selected and (not shape.disabled or self.showDisabledPaths) or\
               self.showPathDirections and not shape.disabled:
                start, end = shape.get_start_end_points_physical()
                start = scaleArrow * start.to3D(shape.axis3_start_mill_depth)
                end = scaleArrow * end.to3D(shape.axis3_mill_depth)
                self.gl.glTranslatef(start.x, -start.y, start.z)
                self.gl.glCallList(shape.drawArrowsDirection[0])
                self.gl.glTranslatef(-start.x, start.y, -start.z)
                self.gl.glTranslatef(end.x, -end.y, end.z)
                self.gl.glCallList(shape.drawArrowsDirection[1])
                self.gl.glTranslatef(-end.x, end.y, -end.z)

        self.gl.glCallList(self.wpZero)
        self.gl.glTranslatef(-self.posX / self.scaleCorr, -self.posY / self.scaleCorr, -self.posZ / self.scaleCorr)
        self.gl.glCallList(self.orientation)

    def resizeGL(self, width, height):
        self.gl.glViewport(0, 0, width, height)
        side = min(width, height)
        self.gl.glMatrixMode(self.gl.GL_PROJECTION)
        self.gl.glLoadIdentity()
        if width >= height:
            scale_x = width / height
            self.gl.glOrtho(GLWidget.CAM_LEFT_X * scale_x, GLWidget.CAM_RIGHT_X * scale_x,
                            GLWidget.CAM_BOTTOM_Y, GLWidget.CAM_TOP_Y,
                            GLWidget.CAM_NEAR_Z, GLWidget.CAM_FAR_Z)
        else:
            scale_y = height / width
            self.gl.glOrtho(GLWidget.CAM_LEFT_X, GLWidget.CAM_RIGHT_X,
                            GLWidget.CAM_BOTTOM_Y * scale_y, GLWidget.CAM_TOP_Y * scale_y,
                            GLWidget.CAM_NEAR_Z, GLWidget.CAM_FAR_Z)
        self.scaleCorr = 400 / side
        self.gl.glMatrixMode(self.gl.GL_MODELVIEW)

    def setClearColor(self, c):
        self.gl.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF())

    def setColor(self, c):
        self.setColorRGBA(c.redF(), c.greenF(), c.blueF(), c.alphaF())

    def setColorRGBA(self, r, g, b, a):
        # self.gl.glMaterialfv(self.gl.GL_FRONT, self.gl.GL_DIFFUSE, (r, g, b, a))
        self.gl.glColor4f(r, g, b, a)

    def plotAll(self, shapes):
        for shape in shapes:
            self.paint_shape(shape)
            self.shapes.append(shape)
        self.drawWpZero()
        self.drawOrientationArrows()

    def repaint_shape(self, shape):
        self.gl.glDeleteLists(shape.drawObject, 4)
        self.paint_shape(shape)

    def paint_shape(self, shape):
        shape.drawObject = self.makeShape(shape)  # 1 object
        shape.stmove = StMove(shape)
        shape.drawStMove = self.makeStMove(shape.stmove)  # 1 object
        shape.drawArrowsDirection = self.makeDirArrows(shape)  # 2 objects

    def makeShape(self, shape):
        genList = self.gl.glGenLists(1)
        self.gl.glNewList(genList, self.gl.GL_COMPILE)

        self.gl.glBegin(self.gl.GL_LINES)
        shape.make_path(self.drawHorLine, self.drawVerLine)
        self.gl.glEnd()

        self.gl.glEndList()

        self.topLeft.detTopLeft(shape.topLeft)
        self.bottomRight.detBottomRight(shape.bottomRight)

        return genList

    def makeStMove(self, stmove):
        genList = self.gl.glGenLists(1)
        self.gl.glNewList(genList, self.gl.GL_COMPILE)

        self.gl.glBegin(self.gl.GL_LINES)
        stmove.make_path(self.drawHorLine, self.drawVerLine)
        self.gl.glEnd()

        self.gl.glEndList()

        return genList

    def drawHorLine(self, caller, Ps, Pe):
        self.gl.glVertex3f(Ps.x, -Ps.y, caller.axis3_start_mill_depth)
        self.gl.glVertex3f(Pe.x, -Pe.y, caller.axis3_start_mill_depth)
        self.gl.glVertex3f(Ps.x, -Ps.y, caller.axis3_mill_depth)
        self.gl.glVertex3f(Pe.x, -Pe.y, caller.axis3_mill_depth)

    def drawVerLine(self, caller, Ps):
        self.gl.glVertex3f(Ps.x, -Ps.y, caller.axis3_start_mill_depth)
        self.gl.glVertex3f(Ps.x, -Ps.y, caller.axis3_mill_depth)

    def drawOrientationArrows(self):

        rCone = 0.01
        rCylinder = 0.004
        zTop = 0.05
        zMiddle = 0.02
        zBottom = -0.03
        segments = 20

        arrow = self.gl.glGenLists(1)
        self.gl.glNewList(arrow, self.gl.GL_COMPILE)

        self.drawCone(Point(), rCone, zTop, zMiddle, segments)
        self.drawSolidCircle(Point(), rCone, zMiddle, segments)
        self.drawCylinder(Point(), rCylinder, zMiddle, zBottom, segments)
        self.drawSolidCircle(Point(), rCylinder, zBottom, segments)

        self.gl.glEndList()

        self.orientation = self.gl.glGenLists(1)
        self.gl.glNewList(self.orientation, self.gl.GL_COMPILE)

        self.setColorRGBA(0.0, 0.0, 1.0, 0.5)
        self.gl.glCallList(arrow)

        self.gl.glRotatef(90, 0, 1, 0)
        self.setColorRGBA(1.0, 0.0, 0.0, 0.5)
        self.gl.glCallList(arrow)

        self.gl.glRotatef(90, 1, 0, 0)
        self.setColorRGBA(0.0, 1.0, 0.0, 0.5)
        self.gl.glCallList(arrow)

        self.gl.glEndList()

    def drawWpZero(self):

        r = 0.02
        segments = 20  # must be a multiple of 4

        self.wpZero = self.gl.glGenLists(1)
        self.gl.glNewList(self.wpZero, self.gl.GL_COMPILE)

        self.setColorRGBA(0.2, 0.2, 0.2, 0.7)
        self.drawSphere(r, segments, segments // 4, segments, segments // 4)

        self.gl.glBegin(self.gl.GL_TRIANGLE_FAN)
        self.gl.glVertex3f(0, 0, 0)
        for i in range(segments // 4 + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r)
            # self.gl.glNormal3f(0, -1, 0)
            self.gl.glVertex3f(xy2.x, 0, xy2.y)
        for i in range(segments // 4 + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r)
            # self.gl.glNormal3f(-1, 0, 0)
            self.gl.glVertex3f(0, -xy2.y, -xy2.x)
        for i in range(segments // 4 + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r)
            # self.gl.glNormal3f(0, 0, 1)
            self.gl.glVertex3f(-xy2.y, xy2.x, 0)
        self.gl.glEnd()

        self.setColorRGBA(0.6, 0.6, 0.6, 0.5)
        self.drawSphere(r * 1.25, segments, segments, segments, segments)

        self.gl.glEndList()

    def drawSphere(self, r, lats, mlats, longs, mlongs):
        lats //= 2
        # based on http://www.cburch.com/cs/490/sched/feb8/index.html
        for i in range(mlats):
            lat0 = pi * (-0.5 + i / lats)
            z0 = r * sin(lat0)
            zr0 = r * cos(lat0)
            lat1 = pi * (-0.5 + (i + 1) / lats)
            z1 = r * sin(lat1)
            zr1 = r * cos(lat1)
            self.gl.glBegin(self.gl.GL_QUAD_STRIP)
            for j in range(mlongs + 1):
                lng = 2 * pi * j / longs
                x = cos(lng)
                y = sin(lng)

                self.gl.glNormal3f(x * zr0, y * zr0, z0)
                self.gl.glVertex3f(x * zr0, y * zr0, z0)
                self.gl.glNormal3f(x * zr1, y * zr1, z1)
                self.gl.glVertex3f(x * zr1, y * zr1, z1)
            self.gl.glEnd()

    def drawSolidCircle(self, origin, r, z, segments):
        self.gl.glBegin(self.gl.GL_TRIANGLE_FAN)
        # self.gl.glNormal3f(0, 0, -1)
        self.gl.glVertex3f(origin.x, -origin.y, z)
        for i in range(segments + 1):
            ang = -i * 2 * pi / segments
            xy2 = origin.get_arc_point(ang, r)
            self.gl.glVertex3f(xy2.x, -xy2.y, z)
        self.gl.glEnd()

    def drawCone(self, origin, r, zTop, zBottom, segments):
        self.gl.glBegin(self.gl.GL_TRIANGLE_FAN)
        self.gl.glVertex3f(origin.x, -origin.y, zTop)
        for i in range(segments + 1):
            ang = i * 2 * pi / segments
            xy2 = origin.get_arc_point(ang, r)

            # self.gl.glNormal3f(xy2.x, -xy2.y, zBottom)
            self.gl.glVertex3f(xy2.x, -xy2.y, zBottom)
        self.gl.glEnd()

    def drawCylinder(self, origin, r, zTop, zBottom, segments):
        self.gl.glBegin(self.gl.GL_QUAD_STRIP)
        for i in range(segments + 1):
            ang = i * 2 * pi / segments
            xy = origin.get_arc_point(ang, r)

            # self.gl.glNormal3f(xy.x, -xy.y, 0)
            self.gl.glVertex3f(xy.x, -xy.y, zTop)
            self.gl.glVertex3f(xy.x, -xy.y, zBottom)
        self.gl.glEnd()

    def makeDirArrows(self, shape):
        (start, start_dir), (end, end_dir) = shape.get_start_end_points_physical(None, False)

        startArrow = self.gl.glGenLists(1)
        self.gl.glNewList(startArrow, self.gl.GL_COMPILE)
        self.setColor(GLWidget.COLOR_ENTRY_ARROW)
        self.drawDirArrow(Point3D(), start_dir.to3D(), True)
        self.gl.glEndList()

        endArrow = self.gl.glGenLists(1)
        self.gl.glNewList(endArrow, self.gl.GL_COMPILE)
        self.setColor(GLWidget.COLOR_EXIT_ARROW)
        self.drawDirArrow(Point3D(), end_dir.to3D(), False)
        self.gl.glEndList()

        return startArrow, endArrow

    def drawDirArrow(self, origin, direction, startError):
        offset = 0.0 if startError else 0.05
        zMiddle = -0.02 + offset
        zBottom = -0.05 + offset
        rx, ry, rz = self.getRotationVectors(Point3D(0, 0, 1), direction)

        self.drawArrowHead(origin, rx, ry, rz, offset)

        self.gl.glBegin(self.gl.GL_LINES)
        zeroMiddle = Point3D(0, 0, zMiddle)
        self.gl.glVertex3f(zeroMiddle * rx + origin.x, -zeroMiddle * ry - origin.y, zeroMiddle * rz + origin.z)
        zeroBottom = Point3D(0, 0, zBottom)
        self.gl.glVertex3f(zeroBottom * rx + origin.x, -zeroBottom * ry - origin.y, zeroBottom * rz + origin.z)
        self.gl.glEnd()

    def makeRouteArrowHead(self, start, end):
        if end == start:
            direction = Point3D(0, 0, 1)
        else:
            direction = (end - start).unit_vector()
        rx, ry, rz = self.getRotationVectors(Point3D(0, 0, 1), direction)

        head = self.gl.glGenLists(1)
        self.gl.glNewList(head, self.gl.GL_COMPILE)
        self.drawArrowHead(Point3D(), rx, ry, rz, 0)
        self.gl.glEndList()
        return head

    def drawArrowHead(self, origin, rx, ry, rz, offset):
        r = 0.01
        segments = 10
        zTop = 0 + offset
        zBottom = -0.02 + offset

        self.gl.glBegin(self.gl.GL_TRIANGLE_FAN)
        zeroTop = Point3D(0, 0, zTop)
        self.gl.glVertex3f(zeroTop * rx + origin.x, -zeroTop * ry - origin.y, zeroTop * rz + origin.z)
        for i in range(segments + 1):
            ang = i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r).to3D(zBottom)
            self.gl.glVertex3f(xy2 * rx + origin.x, -xy2 * ry - origin.y, xy2 * rz + origin.z)
        self.gl.glEnd()

        self.gl.glBegin(self.gl.GL_TRIANGLE_FAN)
        zeroBottom = Point3D(0, 0, zBottom)
        self.gl.glVertex3f(zeroBottom * rx + origin.x, -zeroBottom * ry - origin.y, zeroBottom * rz + origin.z)
        for i in range(segments + 1):
            ang = -i * 2 * pi / segments
            xy2 = Point().get_arc_point(ang, r).to3D(zBottom)
            self.gl.glVertex3f(xy2 * rx + origin.x, -xy2 * ry - origin.y, xy2 * rz + origin.z)
        self.gl.glEnd()

    def setShowPathDirections(self, flag):
        self.showPathDirections = flag

    def setShowDisabledPaths(self, flag=True):
        self.showDisabledPaths = flag

    def autoscale(self):
        # TODO currently only works correctly when object is not rotated
        if self.frameSize().width() >= self.frameSize().height():
            aspect_scale_x = self.frameSize().width() / self.frameSize().height()
            aspect_scale_y = 1
        else:
            aspect_scale_x = 1
            aspect_scale_y = self.frameSize().height() / self.frameSize().width()
        scaleX = (GLWidget.CAM_RIGHT_X - GLWidget.CAM_LEFT_X) * aspect_scale_x / (self.bottomRight.x - self.topLeft.x)
        scaleY = (GLWidget.CAM_BOTTOM_Y - GLWidget.CAM_TOP_Y) * aspect_scale_y / (self.topLeft.y - self.bottomRight.y)
        self.scale = min(scaleX, scaleY) * 0.95
        self.posX = ((GLWidget.CAM_LEFT_X + GLWidget.CAM_RIGHT_X) * 0.95 * aspect_scale_x
                     - (self.topLeft.x + self.bottomRight.x) * self.scale) / 2
        self.posY = -((GLWidget.CAM_TOP_Y + GLWidget.CAM_BOTTOM_Y) * 0.95 * aspect_scale_y
                      - (self.topLeft.y + self.bottomRight.y) * self.scale) / 2
        self.posZ = 0
        self.update()

    def topView(self):
        self.rotX = 0
        self.rotY = 0
        self.rotZ = 0
        self.update()

    def isometricView(self):
        self.rotX = -22
        self.rotY = -22
        self.rotZ = 0
        self.update()
Beispiel #50
0
 def __init__(self, point):
     Point.__init__(self, point.x, point.y)
     self.abs_geo = None
Beispiel #51
0
    def find_inter_point_a_a(self, other, type='TIP'):
        """
        Find the intersection between 2 ArcGeo elements. There can be only one
        intersection between 2 lines.
        @param other: the instance of the 2nd geometry element.
        @param type: Can be "TIP" for True Intersection Point or "Ray" for
        Intersection which is in Ray (of Line)
        @return: a list of intersection points.
        @todo: FIXME: The type of the intersection is not implemented up to now
        """
        O_dis = self.O.distance(other.O)

        # If self circle is surrounded by the other no intersection
        if(O_dis < abs(self.r - other.r)):
            return None

        # If other circle is surrounded by the self no intersection
        if(O_dis < abs(other.r - self.r)):
            return None

        # If The circles are to far away from each other no intersection possible
        if (O_dis > abs(other.r + self.r)):
            return None

        # If both circles have the same center and radius
        if abs(O_dis) == 0.0 and abs(self.r - other.r) == 0.0:
            Pi1 = Point(x=self.Ps.x, y=self.Ps.y)
            Pi2 = Point(x=self.Pe.x, y=self.Pe.y)

            return [Pi1, Pi2]
        # The following algorithm was found on :
        # http://www.sonoma.edu/users/w/wilsonst/Papers/Geometry/circles/default.htm

        root = ((pow(self.r + other.r , 2) - pow(O_dis, 2)) *
                  (pow(O_dis, 2) - pow(other.r - self.r, 2)))

        # If the Line is a tangent the root is 0.0.
        if root <= 0.0:
            root = 0.0
        else:
            root = sqrt(root)

        xbase = (other.O.x + self.O.x) / 2 + \
        (other.O.x - self.O.x) * \
        (pow(self.r, 2) - pow(other.r, 2)) / (2 * pow(O_dis, 2))

        ybase = (other.O.y + self.O.y) / 2 + \
        (other.O.y - self.O.y) * \
        (pow(self.r, 2) - pow(other.r, 2)) / (2 * pow(O_dis, 2))

        Pi1 = Point(x=xbase + (other.O.y - self.O.y) / \
                          (2 * pow(O_dis, 2)) * root,
                    y=ybase - (other.O.x - self.O.x) / \
                    (2 * pow(O_dis, 2)) * root)

        Pi1.v1 = self.dif_ang(self.Ps, Pi1, self.ext) / self.ext
        Pi1.v2 = other.dif_ang(other.Ps, Pi1, other.ext) / other.ext

        Pi2 = Point(x=xbase - (other.O.y - self.O.y) / \
                         (2 * pow(O_dis, 2)) * root,
                    y=ybase + (other.O.x - self.O.x) / \
                    (2 * pow(O_dis, 2)) * root)

        Pi2.v1 = self.dif_ang(self.Ps, Pi2, self.ext) / self.ext
        Pi2.v2 = other.dif_ang(other.Ps, Pi2, other.ext) / other.ext


        if type == 'TIP':
            if ((Pi1.v1 >= 0.0 and Pi1.v1 <= 1.0 and Pi1.v2 > 0.0 and Pi1.v2 <= 1.0) and
               (Pi2.v1 >= 0.0 and Pi2.v1 <= 1.0 and Pi2.v2 > 0.0 and Pi2.v2 <= 1.0)):
                if (root == 0):
                    return Pi1
                else:
                    return [Pi1, Pi2]
            elif (Pi1.v1 >= 0.0 and Pi1.v1 <= 1.0 and Pi1.v2 > 0.0 and Pi1.v2 <= 1.0):
                return Pi1
            elif  (Pi2.v1 >= 0.0 and Pi2.v1 <= 1.0 and Pi2.v2 > 0.0 and Pi2.v2 <= 1.0):
                return Pi2
            else:
                return None
        elif type == "Ray":
            # If the root is zero only one solution and the line is a tangent.
            if root == 0:
                return Pi1
            else:
                return [Pi1, Pi2]
        else:
            logger.error("We should not be here")
Beispiel #52
0
 def __init__(self, lat, lon, placeText):
     Point.__init__(self, lat, lon, message=placeText)
     self._name = placeText.split(",")[0]
     self.description = re.sub(",", "\n", placeText)  # replace separators with newlines