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
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
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)
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
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
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
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
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
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
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 + "!")
) 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)