예제 #1
0
def cast_planes_on_screen(planes, width, height, distance_to_screen,
                          clipping_distance):
    # clipping plane
    plane_point1 = Point(20, 2, clipping_distance)
    plane_point2 = Point(1, 1, clipping_distance)
    plane_point3 = Point(2, 30, clipping_distance)
    plane_points = [plane_point1, plane_point2, plane_point3]

    # return in correct render order
    cpy_planes = planes.copy()
    cpy_planes.sort()

    screen_planes = []
    for plane in cpy_planes:

        points = []
        for idx, point in enumerate(plane.points):
            # Find clipping
            if point.z <= clipping_distance:
                previousp = plane.points[idx - 1]
                nextp = plane.points[(idx + 1) % len(plane.points)]

                # clip to prevous
                if previousp.z > clipping_distance:
                    cline = clip_line(Line(point, previousp, plane.color),
                                      plane_points)
                    s_point = cast_point_on_screen(cline.start, width, height,
                                                   distance_to_screen)
                    points.append(s_point)

                # clip to next
                if nextp.z > clipping_distance:
                    cline = clip_line(Line(point, nextp, plane.color),
                                      plane_points)
                    s_point = cast_point_on_screen(cline.start, width, height,
                                                   distance_to_screen)
                    points.append(s_point)

                continue

            s_point = cast_point_on_screen(point, width, height,
                                           distance_to_screen)
            points.append(s_point)

        if len(points) == 0:
            continue

        screen_planes.append(Plane(points, plane.color))

    return screen_planes
예제 #2
0
def cast_lines_on_screen(lines, width, height, distance_to_screen,
                         clipping_distance):
    # clipping plane
    plane_point1 = Point(20, 2, clipping_distance)
    plane_point2 = Point(1, 1, clipping_distance)
    plane_point3 = Point(2, 30, clipping_distance)
    plane_points = [plane_point1, plane_point2, plane_point3]

    screen_lines = []
    for line in lines:
        line_to_draw = line
        # skip lines that are behind the clipping plane
        if (line.start.z <= clipping_distance
                and line.end.z <= clipping_distance):
            continue
        # clip lines that go through the clipping plane if needed
        line_to_draw = clip_line(line, plane_points)

        # cast
        points = []
        for point in line_to_draw.get_points():
            s_point = cast_point_on_screen(point, width, height,
                                           distance_to_screen)
            points.append(s_point)

        screen_lines.append(Line(points[0], points[1], line.color))

    return screen_lines
예제 #3
0
def clip_line(line: Line, plane_points: list):
    # check if the line has clipping point
    clipping_z = plane_points[0].z
    if (line.start.z < clipping_z and line.end.z < clipping_z
            or line.start.z > clipping_z and line.end.z > clipping_z):
        return line

    p0 = np.array([plane_points[0].x, plane_points[0].y, plane_points[0].z])
    p1 = np.array([plane_points[1].x, plane_points[1].y, plane_points[1].z])
    p2 = np.array([plane_points[2].x, plane_points[2].y, plane_points[2].z])

    p01 = p1 - p0
    p02 = p2 - p0

    la = np.array([line.start.x, line.start.y, line.start.z])
    lb = np.array([line.end.x, line.end.y, line.end.z])
    lab = lb - la

    # evaluate the point that is still visible
    if line.start.z < p0[2] or np.isclose(line.start.z, p0[2]):
        visible_point = line.end
    else:
        visible_point = line.start

    # calculate clipping point
    t = (p01.dot(p02) * (la - p0)) / (-lab * p01.dot(p02))
    clipping_point = la + lab.dot(t[2])
    clipping_point = Point(clipping_point[0], clipping_point[1],
                           clipping_point[2])

    return Line(clipping_point, visible_point, line.color)
예제 #4
0
 def generate_square(self):
     result = []
     for i in xrange(0, self._diagonal_n):
         idx = random.randint(0, 1)
         line = Line.get_line(self._square[idx], self._square[idx + 2])
         x = line.delta_x() * random.random() + line.get_lower_x()
         y = line.get_y(x)
         result.append(Point(x, y))
     # kwadrat jest czworokątem, więc punkty na nim generujemy z napisanej już metody
     result.extend(self.generate_quadrilateral(n=self._square_n, quadra=self._square))
     self._generated = result
     return result
예제 #5
0
def translate_lines(lines, x, y, z):
    new_lines = []
    for line in lines:

        points = []
        for point in line.get_points():
            new_point = Point(point.x + x, point.y + y, point.z + z)
            points.append(new_point)

        new_lines.append(Line(points[0], points[1], line.color))

    return new_lines
예제 #6
0
 def generate_square(self):
     result = []
     for i in xrange(0, self._diagonal_n):
         idx = random.randint(0, 1)
         line = Line.get_line(self._square[idx], self._square[idx + 2])
         x = line.delta_x() * random.random() + line.get_lower_x()
         y = line.get_y(x)
         result.append(Point(x, y))
     # kwadrat jest czworokątem, więc punkty na nim generujemy z napisanej już metody
     result.extend(
         self.generate_quadrilateral(n=self._square_n, quadra=self._square))
     self._generated = result
     return result
예제 #7
0
def rotate_lines(lines, angle, axis):
    angle = angle * math.pi / 180
    rotation_matrix = get_rotation_matrix(angle, axis)

    new_lines = []
    for line in lines:
        points = []
        for point in line.get_points():
            new_point = np.dot(rotation_matrix, [point.x, point.y, point.z, 1])
            new_point = Point(new_point[0], new_point[1], new_point[2])
            points.append(new_point)

        new_lines.append(Line(points[0], points[1], line.color))

    return new_lines
예제 #8
0
파일: algorithm.py 프로젝트: ikostia/glyphs
    def run(self, glyph):
        if glyph.orientation == HORIZONTAL:
            level_coord = 1
        else:
            level_coord = 0
        dim_coord = 1 - level_coord

        seqs = {}
        for line in glyph.lines:
            for point in xrange(line[dim_coord], line[dim_coord] + line.l):
                seq = seqs.get(point, SegmentSequence())
                seq.add_point(line[level_coord])
                seqs[point] = seq

        level_coord, dim_coord = dim_coord, level_coord
        result = Glyph(orientation=not glyph.orientation)
        for level, sequence in seqs.items():
            for segment in sequence:
                line = Line(l=len(segment))
                line[level_coord] = level
                line[dim_coord] = segment.start
                result.add_line(line)

        return result
예제 #9
0
    def generate_quadrilateral(self, n=None, quadra=None):
        if not n:
            n = self._n
        if not quadra:
            quadra = self._quadra
        result = []
        for i in xrange(0, n):
            # losujemy 2 punkty leżące na jednym boku
            idx = random.randint(0, 3)
            x1 = quadra[idx]
            x2 = quadra[idx + 1] if idx != 3 else quadra[0]

            line = Line.get_line(x1, x2)
            x = line.delta_x() * random.random() + line.get_lower_x()

            # jeśli jest to normalna funkcja liczymy y z wzoru f(x) = ax + b
            if line.is_ok():
                y = line.get_y(x)
            # w przeciwnym wypadku losujemy położenie y pomiędzy dwoma punktami
            else:
                y = line.delta_y() * random.random() + line.get_lower_y()
            result.append(Point(x, y))
        self._generated = result
        return result
예제 #10
0
    def generate_quadrilateral(self, n=None, quadra=None):
        if not n:
            n = self._n
        if not quadra:
            quadra = self._quadra
        result = []
        for i in xrange(0, n):
            # losujemy 2 punkty leżące na jednym boku
            idx = random.randint(0, 3)
            x1 = quadra[idx]
            x2 = quadra[idx + 1] if idx != 3 else quadra[0]

            line = Line.get_line(x1, x2)
            x = line.delta_x() * random.random() + line.get_lower_x()

            # jeśli jest to normalna funkcja liczymy y z wzoru f(x) = ax + b
            if line.is_ok():
                y = line.get_y(x)
            # w przeciwnym wypadku losujemy położenie y pomiędzy dwoma punktami
            else:
                y = line.delta_y() * random.random() + line.get_lower_y()
            result.append(Point(x, y))
        self._generated = result
        return result
예제 #11
0
def read_setup(fname):
    f = open(fname, "r")
    if f.mode == 'r':
        lines = []
        planes = []

        points = {}
        for idx, file_line in enumerate(f.readlines()):
            # Lines starting with P define a Point
            # e.g. P pointID 300 300 300
            if file_line[0] == 'P':
                # validate line
                if len(
                        re.findall(r'P [A-Za-z]+ (([-+]?(\d+\.?\d*)) ?){3}',
                                   file_line)) != 1:
                    raise Exception("Line " + idx +
                                    " has unsupported data format!")

                # parse data
                point_id = re.findall(r'[A-Za-z]+', file_line)[1]
                coords = re.findall(r'[-+]?\d+\.?\d*', file_line)
                coords = [float(i) for i in coords]

                # create a point
                point = Point(coords[0], coords[1], coords[2])
                points[point_id] = point

            # Lines starting with C define a connection
            # e.g. 'C pointID_A pointID_V 1 0 0 1'
            elif file_line[0] == 'C':
                # validate line
                if len(
                        re.findall(
                            r'C [A-Za-z]+ [A-Za-z]+ (([-+]?(\d+\.?\d*)) ?){4}',
                            file_line)) != 1:
                    raise Exception("Line " + idx +
                                    " has unsupported data format!")

                # parse data
                point_ids = re.findall(r'[A-Za-z]+', file_line)[1:3]
                color = re.findall(r'[-+]?\d+\.?\d*', file_line)
                color = [float(i) for i in color]

                # connect points
                line = Line(points[point_ids[0]], points[point_ids[1]], color)
                lines.append(line)

            # Lines starting with C define a connection
            # e.g. 'O frontDownLeft frontUpLeft backUpLeft backDownLeft 1 1 1 1'
            elif file_line[0] == 'O':
                # validate line
                if len(
                        re.findall(r'O ([A-Za-z]+ )+(([-+]?(\d+\.?\d*)) ?){4}',
                                   file_line)) != 1:
                    raise Exception("Line " + idx +
                                    " has unsupported data format!")

                # parse data
                point_ids = re.findall(r'[A-Za-z]+', file_line)[1:]
                color = re.findall(r'[-+]?\d+\.?\d*', file_line)
                color = [float(i) for i in color]

                # create plane
                plane_points = []
                for pid in point_ids:
                    plane_points.append(points[pid])

                planes.append(Plane(plane_points, color))

        return lines, planes
    else:
        raise Exception("Couldn't read file: " + fname + "!")
예제 #12
0
)


def from_python(obj):
    if obj is None:
        return {'length': -1}
    return {'length': len(obj), 'data': obj}


def to_python(obj):
    if obj['length'] == -1:
        return None
    return obj['data']


simple_string = Line()


class RedisError(Exception):
    pass


error = Adapted(
    Line(),
    before_build=lambda obj: str(obj),
    after_parse=lambda obj: RedisError(obj),
)

integer = Adapted(Line(), before_build=str, after_parse=int)