コード例 #1
0
    def fromFoci(cls, f1, f2, f3):
        """Create an ellipse from foci.
            f1 and f2 are foci
            f3 is the axis_b

             /----f3----\
            /            \
            |  f1    f2  |
            \            /
             \----------/
        """
        if not isinstance(f1, (QgsPoint, CADPoint)) \
            or not isinstance(f2,
                              (QgsPoint, CADPoint)) \
            or not isinstance(f3,
                              (QgsPoint, CADPoint)):
            raise AttributeError

        f1 = CADPoint(f1)
        f2 = CADPoint(f2)
        f3 = CADPoint(f3)

        dist_f1f2 = f1.distance(f2)
        dist_f1f3 = f1.distance(f3)
        dist_f2f3 = f2.distance(f3)

        dist_tot = dist_f1f3 + dist_f2f3
        angle_exist = f1.getAngleOfLineBetweenTwoPoints(f2)
        center_f1f2 = f1.midpoint(f2)

        axis_a = dist_tot / 2.0
        axis_b = math.sqrt((dist_tot / 2.0)**2.0 - (dist_f1f2 / 2.0)**2.0)

        return cls(center_f1f2, axis_a, axis_b, angle_exist)
コード例 #2
0
    def byCenter2Points(cls, pc, p1, p2):
        """Create an ellipse by center and 2 points for axis.

             /----p2----\
            /            \
            |     pc     p1
            \            /
             \----------/
        """
        if not isinstance(pc, (QgsPoint, CADPoint)) \
            or not isinstance(p1,
                              (QgsPoint, CADPoint)) \
            or not isinstance(p2,
                              (QgsPoint, CADPoint)):
            raise AttributeError

        pc = CADPoint(pc)
        p1 = CADPoint(p1)
        p2 = CADPoint(p2)

        angle_exist = pc.getAngleOfLineBetweenTwoPoints(p1)

        axis_a = pc.distance(p1)

        pp = CADLine.pointOnALine(CADLine(pc, p1), p2)
        length = p2.distance(pp)
        pp2 = pc.pointProjected(length, 90 + angle_exist)
        axis_b = pc.distance(pp2)

        return cls(pc, axis_a, axis_b, angle_exist)
コード例 #3
0
    def by2Corners(cls, p1, p2, nbEdges=5):
        """CADRegularPolygon by 2 corners (AB):
           A----B
          /      \
         /        \
         \        /
          \------/
          """
        if not isinstance(p1, (QgsPoint, CADPoint)) or \
           not isinstance(p2, (QgsPoint, CADPoint)) or \
           not isinstance(nbEdges, (long, int)):
            raise AttributeError
        else:
            p1 = CADPoint(p1)
            p2 = CADPoint(p2)
            angle_exist = p1.getAngleOfLineBetweenTwoPoints(p2)
            pm = p1.midpoint(p2)
            length = p1.distance(pm)

            angle = (180.0 - (360.0 / nbEdges)) / 2.0
            hypo = length / math.cos(math.radians(angle))
            pc = p1.pointProjected(hypo, angle_exist + angle)

            return cls(pc, p1, nbEdges)

        return None
コード例 #4
0
    def by3Points(cls, p1, p2, p3):
        """Create a CADRectangle with 2 points (AD) and a length (X - AD)
        D-------C
        |       X
        A-------B
        """
        if not isinstance(p1, (CADPoint, QgsPoint)) or \
           not isinstance(p2, (CADPoint, QgsPoint)) or \
           not isinstance(p3, (CADPoint, QgsPoint)):
            raise AttributeError

        p1 = CADPoint(p1)
        p2 = CADPoint(p2)
        p3 = CADPoint(p3)

        l = CADLine(p1, p2)
        angle_exist = p1.getAngleOfLineBetweenTwoPoints(p2)
        side = CADPoint.isCollinear(p1, p2, p3)
        if side == 0:
            return None

        pp = CADLine.pointOnALine(CADLine(p1, p2), p3)

        length = p3.distance(pp) * side

        p3 = p2.pointProjected(length, 90 + angle_exist)
        p4 = p1.pointProjected(length, 90 + angle_exist)

        return cls(p1, p2, p3, p4)
コード例 #5
0
    def by2PointsAndWidth(cls, p1, p2, w):
        """Create a CADRectangle with 2 points (AD) and the width
        D-------C
        |       |
        A-------B
        """

        if not isinstance(p1, (CADPoint, QgsPoint)) or \
           not isinstance(p2, (CADPoint, QgsPoint)) or \
           not isinstance(w, (float, long, int)):
            raise AttributeError

        p1 = CADPoint(p1)
        p2 = CADPoint(p2)

        angle_exist = p1.getAngleOfLineBetweenTwoPoints(p2)

        pt1 = p1
        pt2 = p1.pointProjected(w, 90 - angle_exist)
        pt3 = p2.pointProjected(w, 90 - angle_exist)
        pt4 = p2

        l = CADLine(p1, p2)
        if CADPoint.isCollinear(pt1, pt2, pt3) == 0:
            pt2 = p1.pointProjected(w, 90 + angle_exist)
            pt3 = p2.pointProjected(w, 90 + angle_exist)

        return cls(pt1, pt2, pt3, pt4)
コード例 #6
0
    def byCenter2Points(cls, ptCenter, ptStart, ptEnd, direction=1):
        """Create a CADCirclurArc with by Center C and 2 points AB
         A   C    B
         |        |
          \------/
        """
        if all([isinstance(p, (CADPoint, QgsPoint))
                for p in [ptCenter, ptStart, ptEnd]]) and \
           isinstance(direction, (int, long)):
            ptCenter = CADPoint(ptCenter)
            ptStart = CADPoint(ptStart)
            ptEnd = CADPoint(ptEnd)

            a1 = ptCenter.getAngleOfLineBetweenTwoPoints(ptStart)
            a2 = ptCenter.getAngleOfLineBetweenTwoPoints(ptEnd)
            return cls.byCenterPointAngle(ptCenter, ptStart, a2 - a1,
                                          direction)
コード例 #7
0
    def byCenterPointAngle(cls, ptCenter, ptStart, inAngle, direction=1):
        """Create a CADCirclurArc with by Center C a point A and angle
         A   C
         |
          \------/Angle
        """
        if not all([isinstance(p, (CADPoint, QgsPoint))
                    for p in [ptCenter, ptStart]]) or \
           not isinstance(inAngle, (int, long, float)) or \
           not isinstance(direction, (int, long)):
            raise AttributeError

        ptCenter = CADPoint(ptCenter)
        ptStart = CADPoint(ptStart)
        angle = ptCenter.getAngleOfLineBetweenTwoPoints(ptStart)
        dist = ptCenter.distance(ptStart)

        if inAngle < 0:
            inAngle += 360
        ptAngle = 0
        if direction == 1:
            ptAngle = angle - (360 - inAngle)
        elif direction == -1:
            ptAngle = angle + inAngle

        ptEnd = ptCenter.pointProjected(dist, ptAngle)
        ptAngle_arc = ptCenter.getAngleOfLineBetweenTwoPoints(
            ptStart.midpoint(ptEnd))
        if direction == 1:
            if inAngle < 180:
                ptAngle_arc = ptAngle_arc + 180
        if direction == -1:
            if inAngle > 180:
                ptAngle_arc = ptAngle_arc - 180
        ptArc = ptCenter.pointProjected(dist, ptAngle_arc)

        return cls(ptStart, ptEnd, ptArc)
コード例 #8
0
    def rotate(self, pr, a):
        """Rotate a CADRectangle with angle `a` and base point `pr`
        D-------C
        |       |
        A-------B
        """
        if not isinstance(pr, (CADPoint, QgsPoint)) \
            or not isinstance(a,
                              (float, long, int)):
            pass
        else:
            pr = CADPoint(pr)

            dist = [pr.distance(i) for i in self.__points]
            angle_exist = [
                pr.getAngleOfLineBetweenTwoPoints(p) for p in self.__points
            ]
            for i, p in enumerate(self.__points):
                self.__points[i] = pr.pointProjected(dist[i],
                                                     angle_exist[i] + a)
            self.__update()
コード例 #9
0
class CADRegularPolygon(object):
    def __init__(self, pCenter, pCorner, nbEdges=5):
        if not isinstance(pCenter, (QgsPoint, CADPoint)) \
            or not isinstance(pCorner, (QgsPoint, CADPoint)) \
            or not isinstance(nbEdges,
                              (long, int)):
            raise AttributeError
        else:
            self._center = CADPoint(pCenter)
            self._corner = CADPoint(pCorner)
            self._nbEdges = nbEdges
            self.__points = self.__updatePoints()
            # self._angle

    def __str__(self):
        s = "Regular polygon:\n" + \
            "Edges: {}".format(self._nbEdges) + '\n' + \
            "Center: {}".format(self._center) + '\n' + \
            "Corner: {}".format(self._corner) + '\n'
        return s

    def __repr__(self, precision=3):
        s = "CADRegularPolygon("
        s += "QgsPoint(%s)" % self._center
        s += ", QgsPoint(%s)" % self._corner
        s += ", %s)" % self._nbEdges

        return s

    def __eq__(self, other):
        if not isinstance(other, (QgsPoint, CADPoint)):
            raise AttributeError

        if CADPoint.pointsCompare(self._center, other._center) \
                and self._nbEdges == other._nbEdges:
            return True

        return False

    def __iter__(self):
        i = 0
        while i < self._nbEdges:
            yield self.__points[i]
            i += 1

    def __update(self):
        self.__updatePoints()
        self.__updateRadius()
        self.__updateAngle()

    def __updateAngle(self):
        self._angle = self._center.getAngleOfLineBetweenTwoPoints(self._corner)

    def __updateRadius(self):
        self._radius = self._center.distance(self._corner)

    def __updatePoints(self):
        n = 1
        center = self._center
        corner = self._corner

        r = center.distance(corner)

        points = []
        angle_add = 2 * math.pi / self._nbEdges

        angle_start = math.atan2(corner.y - center.y, corner.x - center.x)

        angle = angle_start

        while (n <= self._nbEdges):

            angle += angle_add
            if angle_add > 0.0 and angle > math.pi:
                angle -= 2 * math.pi

            c2 = center.pointProjected(r, math.degrees(angle))

            points.append(c2)

            n += 1

        return points

    @property
    def nbEdges(self):
        """Return the number of sides/edges of the RegularPolygon
        """
        return self._nbEdges

    @nbEdges.setter
    def nbEdges(self, n):
        """Set the number of sides/edges of the RegularPolygon
        """
        if not isinstance(n, (int, long)):
            raise AttributeError
        self._nbEdges = n
        self.__update()

    @property
    def center(self):
        """The center of the RegularPolygon
        This is also the center of the circumscribing circle.
        """
        return self._center

    @center.setter
    def center(self, pc):
        """Set the center of the RegularPolygon
        """
        if not isinstance(pc, (QgsPoint, CADPoint)):
            raise AttributeError

        angle_exist = self._rotation
        dist_exist = self._radius
        self._center = CADPoint(pc)
        self._corner = self._center.pointProjected(dist_exist, angle_exist)
        self._update()

    @property
    def circumcenter(self):
        """
        Alias for center.
        """
        return self.center

    @property
    def corner(self):
        """Return the first corner (edge) of the RegularPolygon
        """
        return self._corner

    @corner.setter
    def corner(self, pc):
        """Set the first corner (edge) of the RegularPolygon
        """
        if not isinstance(pc, (QgsPoint, CADPoint)):
            raise AttributeError
        self._corner = CADPoint(pc)
        self.__update()

    @property
    def length(self):
        """Return the length of the sides.
        """
        return self._radius * 2 * math.sin(math.pi / self._nbEdges)

    @property
    def radius(self):
        """Radius of the RegularPolygon
        This is also the radius of the circumscribing circle.
        """
        return self._radius

    @property
    def circumradius(self):
        """
        Alias for radius.
        """
        return self.radius

    @property
    def angle(self):
        """Angle by which the RegularPolygon is rotated
        """
        return self._angle

    @property
    def apothem(self):
        """The inradius of the RegularPolygon.
        The apothem/inradius is the radius of the inscribed circle.
        """
        return self.radius * math.cos(math.pi / self._nbEdges)

    @property
    def inradius(self):
        """
        Alias for apothem.
        """
        return self.apothem

    @property
    def interior_angle(self):
        """Measure of the interior angles.
        """
        return (self._nbEdges - 2) * math.pi / self._nbEdges

    @property
    def exterior_angle(self):
        """Measure of the exterior angles.
        """
        return 2 * math.pi / self._nbEdges

    @property
    def circumcircle(self):
        """The circumcircle of the RegularPolygon.
        """
        return CADCircle(self.center, self.radius)

    @property
    def incircle(self):
        """The incircle of the RegularPolygon.
        """
        return CADCircle(self.center, self.apothem)

    @property
    def area(self):
        """Returns the area.
        """
        r, n, l = self._radius, self._nbEdges, self.length
        return r * n * l**2 / (4 * math.tan(math.pi / n))

    @classmethod
    def by2Corners(cls, p1, p2, nbEdges=5):
        """CADRegularPolygon by 2 corners (AB):
           A----B
          /      \
         /        \
         \        /
          \------/
          """
        if not isinstance(p1, (QgsPoint, CADPoint)) or \
           not isinstance(p2, (QgsPoint, CADPoint)) or \
           not isinstance(nbEdges, (long, int)):
            raise AttributeError
        else:
            p1 = CADPoint(p1)
            p2 = CADPoint(p2)
            angle_exist = p1.getAngleOfLineBetweenTwoPoints(p2)
            pm = p1.midpoint(p2)
            length = p1.distance(pm)

            angle = (180.0 - (360.0 / nbEdges)) / 2.0
            hypo = length / math.cos(math.radians(angle))
            pc = p1.pointProjected(hypo, angle_exist + angle)

            return cls(pc, p1, nbEdges)

        return None

    @classmethod
    def byCenterAndCorner(cls, p1, p2, nbEdges=5):
        """CADRegularPolygon by center C and a corner A:
           A-----
          /      \
         /    C   \
         \        /
          \------/
          """
        if not isinstance(p1, (QgsPoint, CADPoint)) or \
           not isinstance(p2, (QgsPoint, CADPoint)) or \
           not isinstance(nbEdges, (long, int)):
            raise AttributeError
        else:
            return cls(p1, p2, nbEdges)

        return None

    def exportToQgsGeometry(self):
        """Export CADRegularPolygon to a QgsGeometry (Polygon)"""
        return QgsGeometry.fromPolygon(
            [[QgsPoint(p.x, p.y) for p in self.__points]])