def isPtOnArc(self, point): dist = qad_utils.getDistance(self.center, point) if qad_utils.doubleNear(self.radius, dist): angle = qad_utils.getAngleBy2Pts(self.center, point) return qad_utils.isAngleBetweenAngles(self.startAngle, self.endAngle, angle) else: return False
def fromPolyline(self, points, startVertex, atLeastNSegment=None): """ setta le caratteristiche del primo arco incontrato nella lista di punti partendo dalla posizione startVertex (0-indexed) ritorna la posizione nella lista del punto iniziale e finale se é stato trovato un arco altrimenti None N.B. in punti NON devono essere in coordinate geografiche """ if atLeastNSegment is None: _atLeastNSegment = QadVariables.get(QadMsg.translate("Environment variables", "ARCMINSEGMENTQTY"), 12) else: _atLeastNSegment = atLeastNSegment totPoints = len(points) # perché sia un arco ci vogliono almeno _atLeastNSegment segmenti if (totPoints - 1) - startVertex < _atLeastNSegment or _atLeastNSegment < 2: return None # per problemi di approssimazione dei calcoli epsilon = 1.0e-4 # percentuale del raggio per ottenere max diff. di una distanza con il raggio InfinityLinePerpOnMiddle1 = None InfinityLinePerpOnMiddle2 = None nSegment = 0 i = startVertex while i < totPoints - 1: if InfinityLinePerpOnMiddle1 is None: InfinityLinePerpOnMiddle1 = qad_utils.getInfinityLinePerpOnMiddle(points[i], points[i + 1]) nStartVertex = i nSegment = 1 i = i + 1 continue elif InfinityLinePerpOnMiddle2 is None: InfinityLinePerpOnMiddle2 = qad_utils.getInfinityLinePerpOnMiddle(points[i], points[i + 1]) if InfinityLinePerpOnMiddle2 is None: InfinityLinePerpOnMiddle1 = None nSegment = 0 else: # calcolo il presunto centro con 2 segmenti center = qad_utils.getIntersectionPointOn2InfinityLines( InfinityLinePerpOnMiddle1[0], InfinityLinePerpOnMiddle1[1], InfinityLinePerpOnMiddle2[0], InfinityLinePerpOnMiddle2[1], ) if center is None: # linee parallele InfinityLinePerpOnMiddle1 = InfinityLinePerpOnMiddle2 InfinityLinePerpOnMiddle2 = None nStartVertex = i nSegment = 1 else: nSegment = nSegment + 1 radius = qad_utils.getDistance(center, points[i + 1]) # calcolo il presunto raggio maxDifference = radius * epsilon # calcolo il verso dell'arco e l'angolo dell'arco # se un punto intermedio dell'arco è a sinistra del # segmento che unisce i due punti allora il verso è antiorario startClockWise = ( True if qad_utils.leftOfLine(points[i], points[i - 1], points[i + 1]) < 0 else False ) angle = qad_utils.getAngleBy3Pts(points[i - 1], center, points[i + 1], startClockWise) else: # e sono già stati valutati almeno 2 segmenti # calcolo la distanza del punto dal presunto centro dist = qad_utils.getDistance(center, points[i + 1]) # calcolo il verso dell'arco e l'angolo clockWise = True if qad_utils.leftOfLine(points[i], points[i - 1], points[i + 1]) < 0 else False angle = angle + qad_utils.getAngleBy3Pts(points[i], center, points[i + 1], startClockWise) # se la distanza è così vicina a quella del raggio # il verso dell'arco deve essere quello iniziale # l'angolo dell'arco non può essere >= 360 gradi if ( qad_utils.doubleNear(radius, dist, maxDifference) and startClockWise == clockWise and angle < 2 * math.pi ): nSegment = nSegment + 1 # anche questo segmento fa parte dell'arco else: # questo segmento non fa parte del cerchio # se sono stati trovati un numero sufficiente di segmenti successivi if nSegment >= _atLeastNSegment: # se é un angolo giro e il primo punto = ultimo punto allora points é un cerchio if qad_utils.doubleNear(angle, 2 * math.pi) and points[0] == points[-1]: return None break else: i = i - 2 InfinityLinePerpOnMiddle1 = None InfinityLinePerpOnMiddle2 = None i = i + 1 # se sono stati trovati un numero sufficiente di segmenti successivi if nSegment >= _atLeastNSegment: nEndVertex = nStartVertex + nSegment # se il punto iniziale e quello finale non coincidono é un arco if points[nStartVertex] != points[nEndVertex]: self.center = center self.radius = radius # se il verso é orario if startClockWise: # inverto l'angolo iniziale con quello finale self.endAngle = qad_utils.getAngleBy2Pts(center, points[nStartVertex]) self.startAngle = qad_utils.getAngleBy2Pts(center, points[nEndVertex]) else: self.startAngle = qad_utils.getAngleBy2Pts(center, points[nStartVertex]) self.endAngle = qad_utils.getAngleBy2Pts(center, points[nEndVertex]) return nStartVertex, nEndVertex return None
def fromPolyline(self, points, startVertex, atLeastNSegment=None): """ setta le caratteristiche del primo arco incontrato nella lista di punti partendo dalla posizione startVertex (0-indexed) ritorna la posizione nella lista del punto iniziale e finale se é stato trovato un arco altrimenti None N.B. in punti NON devono essere in coordinate geografiche """ if atLeastNSegment is None: _atLeastNSegment = QadVariables.get( QadMsg.translate("Environment variables", "ARCMINSEGMENTQTY"), 12) else: _atLeastNSegment = atLeastNSegment totPoints = len(points) # perché sia un arco ci vogliono almeno _atLeastNSegment segmenti if (totPoints - 1) - startVertex < _atLeastNSegment or _atLeastNSegment < 2: return None # per problemi di approssimazione dei calcoli epsilon = 1.e-4 # percentuale del raggio per ottenere max diff. di una distanza con il raggio InfinityLinePerpOnMiddle1 = None InfinityLinePerpOnMiddle2 = None nSegment = 0 i = startVertex while i < totPoints - 1: if InfinityLinePerpOnMiddle1 is None: InfinityLinePerpOnMiddle1 = qad_utils.getInfinityLinePerpOnMiddle( points[i], points[i + 1]) nStartVertex = i nSegment = 1 i = i + 1 continue elif InfinityLinePerpOnMiddle2 is None: InfinityLinePerpOnMiddle2 = qad_utils.getInfinityLinePerpOnMiddle( points[i], points[i + 1]) if InfinityLinePerpOnMiddle2 is None: InfinityLinePerpOnMiddle1 = None nSegment = 0 else: # calcolo il presunto centro con 2 segmenti center = qad_utils.getIntersectionPointOn2InfinityLines(InfinityLinePerpOnMiddle1[0], \ InfinityLinePerpOnMiddle1[1], \ InfinityLinePerpOnMiddle2[0], \ InfinityLinePerpOnMiddle2[1]) if center is None: # linee parallele InfinityLinePerpOnMiddle1 = InfinityLinePerpOnMiddle2 InfinityLinePerpOnMiddle2 = None nStartVertex = i nSegment = 1 else: nSegment = nSegment + 1 radius = qad_utils.getDistance( center, points[i + 1]) # calcolo il presunto raggio tolerance = radius * epsilon # calcolo il verso dell'arco e l'angolo dell'arco # se un punto intermedio dell'arco è a sinistra del # segmento che unisce i due punti allora il verso è antiorario startClockWise = True if qad_utils.leftOfLine( points[i], points[i - 1], points[i + 1]) < 0 else False angle = qad_utils.getAngleBy3Pts( points[i - 1], center, points[i + 1], startClockWise) prevInfinityLinePerpOnMiddle = InfinityLinePerpOnMiddle2 else: # e sono già stati valutati almeno 2 segmenti notInArc = False currInfinityLinePerpOnMiddle = qad_utils.getInfinityLinePerpOnMiddle( points[i], points[i + 1]) if currInfinityLinePerpOnMiddle is None: notInArc = True else: # calcolo il presunto centro con 2 segmenti currCenter = qad_utils.getIntersectionPointOn2InfinityLines(prevInfinityLinePerpOnMiddle[0], \ prevInfinityLinePerpOnMiddle[1], \ currInfinityLinePerpOnMiddle[0], \ currInfinityLinePerpOnMiddle[1]) if currCenter is None: # linee parallele notInArc = True else: # calcolo il verso dell'arco e l'angolo clockWise = True if qad_utils.leftOfLine( points[i], points[i - 1], points[i + 1]) < 0 else False angle = angle + qad_utils.getAngleBy3Pts( points[i], center, points[i + 1], startClockWise) # se la distanza è così vicina a quella del raggio # il verso dell'arco deve essere quello iniziale # l'angolo dell'arco non può essere >= 360 gradi if qad_utils.ptNear(center, currCenter, tolerance) and \ startClockWise == clockWise and \ angle < 2 * math.pi: nSegment = nSegment + 1 # anche questo segmento fa parte dell'arco prevInfinityLinePerpOnMiddle = currInfinityLinePerpOnMiddle else: notInArc = True # questo segmento non fa parte del cerchio if notInArc: # se sono stati trovati un numero sufficiente di segmenti successivi if nSegment >= _atLeastNSegment: # se é un angolo giro e il primo punto = ultimo punto allora points é un cerchio if qad_utils.doubleNear( angle, 2 * math.pi) and points[0] == points[-1]: return None break else: i = i - 2 InfinityLinePerpOnMiddle1 = None InfinityLinePerpOnMiddle2 = None i = i + 1 # se sono stati trovati un numero sufficiente di segmenti successivi if nSegment >= _atLeastNSegment: nEndVertex = nStartVertex + nSegment # se il punto iniziale e quello finale non coincidono é un arco if points[nStartVertex] != points[nEndVertex]: self.center = center self.radius = radius # se il verso é orario if startClockWise: # inverto l'angolo iniziale con quello finale self.endAngle = qad_utils.getAngleBy2Pts( center, points[nStartVertex]) self.startAngle = qad_utils.getAngleBy2Pts( center, points[nEndVertex]) else: self.startAngle = qad_utils.getAngleBy2Pts( center, points[nStartVertex]) self.endAngle = qad_utils.getAngleBy2Pts( center, points[nEndVertex]) return nStartVertex, nEndVertex return None