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
def __init__(self, Ps=Point(0, 0), Pe=Point(0, 0), hdl=[]): """ Standard method to initialize the class """ self.Ps = Ps self.Pe = Pe
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 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)
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
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, [])
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()
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()
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()
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)
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)
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)
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(), [])
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
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)
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
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])
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
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
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)
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
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)
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 __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
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
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)
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
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)
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
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
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
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
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
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
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 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"))
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()
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)
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
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()
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()
def __init__(self, point): Point.__init__(self, point.x, point.y) self.abs_geo = None
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")
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