Esempio n. 1
0
 def size(self):
     '''Return the area of the patch.
     
     The area can be computed using the standard polygon area formula + signed segment areas of each arc.
     '''
     polygon_area = 0
     for a in self.arcs:
         polygon_area += box_product(a.start_point(), a.end_point())
     polygon_area /= 2.0
     return polygon_area + sum([a.sign * a.segment_area() for a in self.arcs])
Esempio n. 2
0
 def size(self):
     """Return the area of the patch.
     
     The area can be computed using the standard polygon area formula + signed segment areas of each arc.
     """
     polygon_area = 0
     for a in self.arcs:
         polygon_area += box_product(a.start_point(), a.end_point())
     polygon_area /= 2.0
     return polygon_area + sum([a.sign * a.segment_area() for a in self.arcs])
Esempio n. 3
0
    def verify(self):
        '''
        Verify the correctness of the region arcs. Throws an VennRegionException if verification fails
        (or any other exception if it happens during verification).
        '''
        # Verify size of arcs list
        if (len(self.arcs) < 2):
            raise VennRegionException(
                "At least two arcs needed in a poly-arc region")
        if (len(self.arcs) > 4):
            raise VennRegionException(
                "At most 4 arcs are supported currently for poly-arc regions")

        TRIG_TOL = 100 * tol  # We need to use looser tolerance level here because conversion to angles and back is prone to large errors.
        # Verify connectedness of arcs
        for i in range(len(self.arcs)):
            if not np.all(self.arcs[i - 1].end_point() -
                          self.arcs[i].start_point() < TRIG_TOL):
                raise VennRegionException(
                    "Arcs of an poly-arc-gon must be connected via endpoints")

        # Verify that arcs do not cross-intersect except at endpoints
        for i in range(len(self.arcs) - 1):
            for j in range(i + 1, len(self.arcs)):
                ips = self.arcs[i].intersect_arc(self.arcs[j])
                for ip in ips:
                    if not (np.all(
                            abs(ip - self.arcs[i].start_point()) < TRIG_TOL)
                            or np.all(
                                abs(ip - self.arcs[i].end_point()) < TRIG_TOL)
                            ):
                        raise VennRegionException(
                            "Arcs of a poly-arc-gon may only intersect at endpoints"
                        )

                if len(ips) != 0 and (i - j) % len(
                        self.arcs) > 1 and (j - i) % len(self.arcs) > 1:
                    # Two non-consecutive arcs intersect. This is in general not good, but
                    # may occasionally happen when all arcs inbetween have length 0.
                    pass  # raise VennRegionException("Non-consecutive arcs of a poly-arc-gon may not intersect")

        # Verify that vertices are ordered so that at each point the direction along the polyarc changes towards the left.
        # Note that this test only makes sense for polyarcs obtained using circle intersections & subtractions.
        # A "flower-like" polyarc may have its vertices ordered counter-clockwise yet the direction would turn to the right at each of them.
        for i in range(len(self.arcs)):
            prev_arc = self.arcs[i - 1]
            cur_arc = self.arcs[i]
            if box_product(prev_arc.direction_vector(prev_arc.to_angle),
                           cur_arc.direction_vector(
                               cur_arc.from_angle)) < -tol:
                raise VennRegionException(
                    "Arcs must be ordered so that the direction at each vertex changes counter-clockwise"
                )
Esempio n. 4
0
    def verify(self):
        """
        Verify the correctness of the region arcs. Throws an VennRegionException if verification fails
        (or any other exception if it happens during verification).
        """
        # Verify size of arcs list
        if len(self.arcs) < 2:
            raise VennRegionException("At least two arcs needed in a poly-arc region")
        if len(self.arcs) > 4:
            raise VennRegionException("At most 4 arcs are supported currently for poly-arc regions")

        TRIG_TOL = (
            100 * tol
        )  # We need to use looser tolerance level here because conversion to angles and back is prone to large errors.
        # Verify connectedness of arcs
        for i in range(len(self.arcs)):
            if not np.all(self.arcs[i - 1].end_point() - self.arcs[i].start_point() < TRIG_TOL):
                raise VennRegionException("Arcs of an poly-arc-gon must be connected via endpoints")

        # Verify that arcs do not cross-intersect except at endpoints
        for i in range(len(self.arcs) - 1):
            for j in range(i + 1, len(self.arcs)):
                ips = self.arcs[i].intersect_arc(self.arcs[j])
                for ip in ips:
                    if not (
                        np.all(abs(ip - self.arcs[i].start_point()) < TRIG_TOL)
                        or np.all(abs(ip - self.arcs[i].end_point()) < TRIG_TOL)
                    ):
                        raise VennRegionException("Arcs of a poly-arc-gon may only intersect at endpoints")

                if len(ips) != 0 and (i - j) % len(self.arcs) > 1 and (j - i) % len(self.arcs) > 1:
                    # Two non-consecutive arcs intersect. This is in general not good, but
                    # may occasionally happen when all arcs inbetween have length 0.
                    pass  # raise VennRegionException("Non-consecutive arcs of a poly-arc-gon may not intersect")

        # Verify that vertices are ordered so that at each point the direction along the polyarc changes towards the left.
        # Note that this test only makes sense for polyarcs obtained using circle intersections & subtractions.
        # A "flower-like" polyarc may have its vertices ordered counter-clockwise yet the direction would turn to the right at each of them.
        for i in range(len(self.arcs)):
            prev_arc = self.arcs[i - 1]
            cur_arc = self.arcs[i]
            if (
                box_product(prev_arc.direction_vector(prev_arc.to_angle), cur_arc.direction_vector(cur_arc.from_angle))
                < -tol
            ):
                raise VennRegionException(
                    "Arcs must be ordered so that the direction at each vertex changes counter-clockwise"
                )