예제 #1
0
파일: qad_arc.py 프로젝트: resistor4u/QAD
 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
예제 #2
0
 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
예제 #3
0
파일: qad_arc.py 프로젝트: resistor4u/QAD
    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
예제 #4
0
    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