예제 #1
0
    def by3Points(cls, p1, p2, p3, epsilon=1e-8):
        """Create a CADCircle with 3 points ABC
          /------\
         |        |
         A        C
         |        |
          \--B---/
        """
        if not all(isinstance(p, (QgsPoint, CADPoint)) for p in [p1, p2, p3]):
            raise AttributeError

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

        # Paul Bourke's algorithm
        m_Center = CADPoint()
        m_dRadius = -1
        yDelta_a = p2.y - p1.y
        xDelta_a = p2.x - p1.x
        yDelta_b = p3.y - p2.y
        xDelta_b = p3.x - p2.x

        try:
            aSlope = yDelta_a / xDelta_a
        except ZeroDivisionError:
            return None

        try:
            bSlope = yDelta_b / xDelta_b
        except ZeroDivisionError:
            return None

        if (math.fabs(xDelta_a) <= epsilon and math.fabs(yDelta_b) <= epsilon):
            m_Center.x = (0.5 * (p2.x + p3.x))
            m_Center.y = (0.5 * (p1.y + p2.y))
            m_dRadius = m_Center.distance(p1)

            return cls(m_Center, m_dRadius)

        if math.fabs(aSlope-bSlope) <= epsilon:
            return None

        m_Center.x = (
                      (aSlope * bSlope * (p1.y - p3.y) +
                       bSlope * (p1.x + p2.x) -
                       aSlope * (p2.x + p3.x)) /
                      (2.0 * (bSlope - aSlope))
                     )
        m_Center.y = (
                      -1.0 * (m_Center.x - (p1.x + p2.x) / 2.0) /
                      aSlope + (p1.y + p2.y) / 2.0
                     )

        m_dRadius = m_Center.distance(p1)

        return cls(m_Center, m_dRadius)
예제 #2
0
    def intersection(self, other):
        if not isinstance(other, CADLine):
            raise AttributeError

        # public domain function by Darel Rex Finley, 2006
        # http://alienryderflex.com/intersect/
        pt_inter = CADPoint()

        Ax, Ay, Bx, By = self.pointsXY
        Cx, Cy, Dx, Dy = other.pointsXY

        if ((Ax == Bx and Ay == By) or (Cx == Dx and Cy == Dy)):
            return None

        #  (1) Translate the system so that point A is on the origin.
        Bx -= Ax
        By -= Ay
        Cx -= Ax
        Cy -= Ay
        Dx -= Ax
        Dy -= Ay

        #  Discover the length of segment A-B.
        distAB = math.sqrt(Bx * Bx + By * By)

        #  (2) Rotate the system so that point B is on the positive X axis.
        theCos = Bx / distAB
        theSin = By / distAB
        newX = Cx * theCos + Cy * theSin
        Cy = Cy * theCos - Cx * theSin
        Cx = newX
        newX = Dx * theCos + Dy * theSin
        Dy = Dy * theCos - Dx * theSin
        Dx = newX

        #  Fail if the lines are parallel.
        if (Cy == Dy):
            return None

        #  (3) Discover the position of the intersection point along line A-B.
        ABpos = Dx + (Cx - Dx) * Dy / (Dy - Cy)

        #  (4) Apply the discovered position to line A-B
        # in the original coordinate system.
        pt_inter.x = Ax + ABpos * theCos
        pt_inter.y = Ay + ABpos * theSin

        #  Success.
        return pt_inter