Ejemplo n.º 1
0
    def is_within(self, pi_object, resolution=0.0001):
        if isinstance(pi_object, pi_point.Point):
            # uses ray casting algorithm to solve point in polygon

            inf_point = pi_point.Point(
                pi_object.x + self.rect_info.top_left.x +
                self.rect_info.width + 10, pi_object.y)
            ray_line = pi_line.Line(pi_object, inf_point)

            intersecting_points = self.get_intersecting_points(ray_line)

            if len(intersecting_points) % 2 == 0:
                return False

            elif len(intersecting_points) == 1:
                if intersecting_points[i].equal(pi_object):
                    # it's just touching
                    return False

            return True
        elif isinstance(pi_object, pi_line.Line):
            points = self.get_intersecting_points(pi_object)

            if (len(points)) == 1:
                if (self.is_touching(pi_object.start)
                        and not (pi_object.start.equal(points[0]))):
                    return True

                elif (self.is_touching(pi_object.end)
                      and not (pi_object.end.equal(points[0]))):
                    return True
            elif len(points) == 2:
                other_points = [pi_object.start, pi_object.end]

                sorted(other_points, key=self.__filter_x_function)
                sorted(other_points, key=self.__filter_x_function)

                dx_0 = other_points[0].x - points[0].x
                dx_1 = other_points[1].x - points[1].x

                resolution = -1.0 * resolution
                return (dx_0 >= resolution) and (dx_1 >= resolution)

            if self.is_within(pi_object.start) or self.is_within(
                    pi_object.end):
                return True
            elif self.is_touching(pi_object.start) and self.is_touching(
                    pi_object.end):
                return True
            else:
                return False

        return False
Ejemplo n.º 2
0
    def is_touching(self, pi_object):
        if isinstance(pi_object, pi_point.Point):
            # uses raying casting algorithm to solve point in polygon
            inf_point = pi_point.Point(
                pi_object.x + self.rect_info.top_left.x +
                self.rect_info.width + 10, pi_object.y)
            ray_line = pi_line.Line(pi_object, inf_point)

            intersecting_points = self.get_intersecting_points(ray_line)
            return not (len(intersecting_points) % 2 == 0)
        elif isinstance(pi_object, pi_line.Line):
            points = self.get_intersecting_points(pi_object)
            return self.is_touching(pi_object.start) or self.is_touching(
                pi_object.end) or (len(points) > 0)
        else:
            return False

        return False
Ejemplo n.º 3
0
    def get_intersecting_lines(self, spacing=10.0, angle=0.0):
        padding = max(rect_info.width, rect_info.height)
        lines = self.get_shading_lines(spacing, angle, padding)

        intersecting_lines = []
        for i in range(len(lines)):
            line = lines[i]
            intersecting_points = self.get_intersecting_points(line)

            sorted(intersecting_points, key=self.__filter_x_function)

            for j in range(0, max(len(intersecting_points) - 1, 0), 2):
                start = intersecting_points[i]
                end = intersecting_points[j + 1]

                line = pi_line.Line(start, end)
                intersecting_lines.append(line)

        return intersecting_lines
Ejemplo n.º 4
0
    def calculate(self):
        if not self.closed: self.data_points.append(self.data_points[0])

        for i in range(len(self.data_points)):
            point = self.data_points[i]
            self.xs.append(point.x)
            self.ys.append(point.y)

        self.boundary_lines = []
        perimeter = 0

        for i in range(len(self.data_points) - 1):
            start = self.data_points[i]
            end = self.data_points[i + 1]

            self.line = pi_line.Line(start, end)
            self.boundary_lines.append(self.line)

            perimeter += abs(self.line.get_length())

            self.rect_info.top_left = pi_point.Point(min(self.xs),
                                                     min(self.ys))
            self.rect_info.width = max(self.xs) - self.rect_info.top_left.x
            self.rect_info.height = max(self.ys) - self.rect_info.top_left.y
            self.rect_info.bottom_right = pi_point.Point(
                self.rect_info.top_left.x + self.rect_info.width,
                self.rect_info.top_left.y + self.rect_info.height)
            self.rect_info.area = self.rect_info.width * self.rect_info.height
            self.rect_info.radius = math.sqrt(
                pow(self.rect_info.width / 2.0, 2) +
                pow(self.rect_info.height / 2.0, 2)) / 2.0
            self.rect_info.center = pi_point.Point(
                self.rect_info.top_left.x + (self.rect_info.width / 2.0),
                self.rect_info.top_left.y + (self.rect_info.height / 2.0))
            self.rect_info.perimeter = perimeter

            mn = min(self.rect_info.width, self.rect_info.height)
            mx = max(self.rect_info.width, self.rect_info.height)

            self.ratio = 0 if ((mn <= 0) or (mx <= 0)) else mn / mx

        return True
Ejemplo n.º 5
0
    def count_edges(self, angle_threshold):
        count = 1

        def _get_angle(a, b, c):
            return math.acos(((b**2) + (a**2) - (c**2)) / (2.0 * b * a))

        for i in range(len(self.boundary_lines) - 1):
            current_line = self.boundary_lines[i]
            next_line = self.boundary_lines[i + 1]

            a = current_line.length
            b = next_line.length
            c = pi_line.Line(current_line.start, next_line.end).length

            if min(a, b, c) <= 0: continue

            angle = _get_angle(a, b, c)

            if abs(angle) > angle_threshold:
                count += 1

        return count
Ejemplo n.º 6
0
    def get_shading_lines(self, spacing=10.0, angle=0.0, padding=0.0):
        lines = []

        min_x = self.rect_info.top_left.x - padding
        min_y = self.rect_info.top_left.y - padding

        max_x = self.rect_info.bottom_right.x + padding
        max_y = self.rect_info.bottom_right.y + padding

        cx = (max_x - min_x) / 2.0 + min_x
        cy = (max_y - min_y) / 2.0 + min_y

        about_point = pi_point.Point(cx, cy)

        for y in range(min_y, max_y, spacing):
            start = pi_point.Point(min_x, y)
            end = pi_point.Point(max_x, y)
            line = pi_line.Line(start, end)

            line.rotate(angle, about_point)
            lines.append(line)

        return lines