def get_shadow(from_point, mesh): tris = [] for i in range(len(mesh.textures)): if mesh.textures[i].damping_rate() < 1e-3: tris.append(mesh.triangles[i]) ray_sum_sqrt = 3 ray_hit = 0 p1 = tris[0].p1 p2 = tris[0].p2 p3 = tris[0].p3 # make p2 be right-angle point if np.dot(p1.data - p2.data, p3.data - p2.data) > 1e-3: if np.dot(p2.data - p1.data, p3.data - p1.data) < 1e-3: tmp = p2 p2 = p1 p1 = tmp else: tmp = p2 p2 = p3 p3 = tmp interval = 1 / ray_sum_sqrt for i in range(ray_sum_sqrt): for j in range(ray_sum_sqrt): tx = i * interval + interval * np.random.random() px = Point3D(p1.data[0] * (1 - tx) + p2.data[0] * tx, p1.data[1] * (1 - tx) + p2.data[1] * tx, p1.data[2] * (1 - tx) + p2.data[2] * tx) ty = j * interval + interval * np.random.random() py = Point3D(p3.data[0] * (1 - tx) + p2.data[0] * tx, p3.data[1] * (1 - tx) + p2.data[1] * tx, p3.data[2] * (1 - tx) + p2.data[2] * tx) light_target = Point3D((p2.data[0] + px.data[0] + py.data[0]) / 3, (p2.data[1] + px.data[1] + py.data[1]) / 3, (p2.data[2] + px.data[2] + py.data[2]) / 3) shadow_ray = Vector(from_point, light_target) p3d = from_point nearest_dist = None nearest_ipoint = None nearest_triangle = None for tri in range(mesh.triangles.size()): result_ipoint = ray_in_triangle(shadow_ray, mesh.triangles[tri]) if result_ipoint is not None: ppdist = dist(p3d, result_ipoint) if nearest_dist is None or ppdist < nearest_dist: nearest_dist = ppdist nearest_triangle = tri nearest_ipoint = result_ipoint if nearest_ipoint is None or dist(nearest_ipoint, light_target) < 1e-3: ray_hit += 1 return ray_hit / ray_sum_sqrt**2
def _CatmullClarkSubdivision_in(faces,lines,points,face_to_lines,line_to_points,line_to_faces,point_to_lines): #print("old_points:",list((p.data[0],p.data[1],p.data[2]) for p in points)) #print("face_to_lines:",face_to_lines) #print("line_to_points:",line_to_points) #print("line_to_faces:",line_to_faces) #print("point_to_lines:",point_to_lines) face_points=[] for face in faces: temp=[] for l in face: temp.append(l[0].data) temp.append(l[1].data) data=sum(temp)/2/len(face) face_points.append(Point(p=Point3D.create(data))) #print("face_points:",len(face_points),list((p.data[0],p.data[1],p.data[2]) for p in face_points)) edge_points=[] for i in range(len(lines)): temp=[] temp.append(face_points[line_to_faces[i][0]].data) temp.append(face_points[line_to_faces[i][1]].data) temp.append(points[line_to_points[i][0]].data) temp.append(points[line_to_points[i][1]].data) data=sum(temp)/4 edge_points.append(Point(p=Point3D.create(data))) #print("edge_points:",list((p.data[0],p.data[1],p.data[2]) for p in edge_points)) vertes_points=[] for i in range(len(points)): data1=np.array([0.0,0.0,0.0]) data2=np.array([0.0,0.0,0.0]) for j in point_to_lines[i]: data1+=(lines[j][0].data+lines[j][1].data)/2.0/len(point_to_lines[i]) data2+=(face_points[line_to_faces[j][0]].data+face_points[line_to_faces[j][1]].data)/2/len(point_to_lines[i]) points[i].data=(data2+2*data1+(len(point_to_lines[i])-3)*points[i].data)/len(point_to_lines[i]) #print("new_points:",list((p.data[0],p.data[1],p.data[2]) for p in points)) re_faces=[] for i in range(len(face_points)): tmp=[] for j in face_to_lines[i]: for k in line_to_points[j]: if k not in tmp: re_faces.append([]) #print(point_to_lines[k],face_to_lines[i]) eps=list(edge_points[p_i] for p_i in [m for m in point_to_lines[k] if m in face_to_lines[i]] ) #print(eps) for ep in eps: re_faces[-1].extend([ [face_points[i],ep],[points[k],ep] ]) tmp.append(k) #print(len(re_faces),'\n',re_faces[0]) return re_faces
def sample_vector(self, size=1): samples = [] xy = [] for i in range(size): input_x = np.random.random() * 2 - 1 input_y = np.random.random() * 2 - 1 real_x = self.width / 2 * input_x real_y = self.height / 2 * input_y start_vector = Vector(Point3D(real_x, real_y, 0), Point3D(real_x, real_y, -1)) samples.append(start_vector) xy.append((input_x, input_y)) return samples, xy
def test_get_shadow(self): scene = make_shadow_cornell_box() get_shadow(Point3D(0, 0, 0), scene.mesh) for i in range(len(scene.mesh.textures)): if scene.mesh.textures[i].damping_rate() < 1e-3: scene.mesh.triangles.triangles[i, 0], scene.mesh.triangles.triangles[i, 1], scene.mesh.triangles.triangles[i, 2] = \ scene.mesh.triangles.triangles[i, 0], scene.mesh.triangles.triangles[i, 2], scene.mesh.triangles.triangles[i, 1] get_shadow(Point3D(0, 0, 0), scene.mesh) for i in range(len(scene.mesh.textures)): if scene.mesh.textures[i].damping_rate() < 1e-3: scene.mesh.triangles.triangles[i, 0], scene.mesh.triangles.triangles[i, 1], scene.mesh.triangles.triangles[i, 2] = \ scene.mesh.triangles.triangles[i, 2], scene.mesh.triangles.triangles[i, 0], scene.mesh.triangles.triangles[i, 1] get_shadow(Point3D(0, 0, 0), scene.mesh)
def _get_average_point(points): x_sum = 0 y_sum = 0 z_sum = 0 for p in points: x_sum = x_sum + p.data[0] y_sum = y_sum + p.data[1] z_sum = z_sum + p.data[2] Apoint = Point3D(x_sum / len(points), y_sum / len(points), z_sum / len(points)) return Apoint
def get_average_point(points): x_sum = 0 y_sum = 0 z_sum = 0 for p in points: x_sum = x_sum + p.data[0] y_sum = y_sum + p.data[1] z_sum = z_sum + p.data[2] Apoint = Point3D(x_sum / len(points), y_sum / len(points), z_sum / len(points)) #将点的坐标和放入其中进行运算求出其他顶点的坐标 return Apoint
def sample_vector(self, size=1): self.index += 1 self.index %= self.width * self.height h_width, h_height = self.width // 2, self.height // 2 y = (self.index // self.width - h_height) / h_height x = (self.index % self.width - h_width - 1) / h_width samples = [] xy = [] for i in range(size): """ input_x = np.random.random()*2 - 1 input_y = np.random.random()*2 - 1 """ input_x, input_y = x, y real_x = np.tan(self.h_angle / 2) * input_x real_y = np.tan(self.v_angle / 2) * input_y start_vector = Vector(Point3D(0, 0, 0), Point3D(real_x, real_y, -1)) samples.append(start_vector) xy.append((input_x, input_y)) return samples, xy
def test_DOOSabin_subdivision(self): point_test_1 = Point3D(4, 4, 4) point_test_2 = Point3D(4, 4, 0) point_test_3 = Point3D(4, 0, 4) point_test_4 = Point3D(4, 0, 0) point_test_5 = Point3D(0, 4, 4) point_test_6 = Point3D(0, 4, 0) point_test_7 = Point3D(0, 0, 4) point_test_8 = Point3D(0, 0, 0) face_test_1 = [point_test_1, point_test_2, point_test_3, point_test_4] face_test_2 = [point_test_1, point_test_5, point_test_6, point_test_2] face_test_3 = [point_test_1, point_test_5, point_test_7, point_test_3] face_test_4 = [point_test_3, point_test_4, point_test_8, point_test_7] face_test_5 = [point_test_5, point_test_6, point_test_8, point_test_7] face_test_6 = [point_test_2, point_test_4, point_test_8, point_test_6] faces_test = [face_test_1, face_test_2, face_test_3, face_test_4, face_test_5, face_test_6] DOO_Sabin(faces_test, 6)
def ray_in_triangle(ray, triangle, include_start_point=False): """ input: ray is a vector input: triangle is a Triangle output: interact point or None. """ vray = ray.end.data - ray.start.data vnorm = triangle.norm.end.data - triangle.norm.start.data if np.abs(np.dot(vray, vnorm)) < 1e-3: return None tray = triangle.p1.data - ray.start.data alpha = np.dot(tray, vnorm) / np.dot(vray, vnorm) if include_start_point: if alpha < 0: return None else: if alpha <= 0: return None ipoint = alpha * ray.end.data + (1 - alpha) * ray.start.data v1 = triangle.p1.data - ipoint v2 = triangle.p2.data - ipoint v3 = triangle.p3.data - ipoint v1norm = np.linalg.norm(v1) v2norm = np.linalg.norm(v2) v3norm = np.linalg.norm(v3) if v1norm < 1e-6 or v2norm < 1e-6 or v3norm < 1e-6: return None v1 = v1 / np.linalg.norm(v1) v2 = v2 / np.linalg.norm(v2) v3 = v3 / np.linalg.norm(v3) d1 = np.arccos(np.dot(v1, v2)) d2 = np.arccos(np.dot(v2, v3)) d3 = np.arccos(np.dot(v3, v1)) if np.abs(np.sum((d1, d2, d3)) - np.pi * 2) < 1e-3: return Point3D(ipoint[0], ipoint[1], ipoint[2]) else: return None
def __init__(self): tris = Triangles() tris.add_triangle(Triangle(Point3D(0, 0, 0), Point3D(1, 0, 0), Point3D(0, 1, 0))) tris.add_triangle(Triangle(Point3D(0, 1, 0), Point3D(1, 0, 0), Point3D(1, 1, 0))) texs = [PlaneLightSource(), PlaneLightSource()] tex_pos = [None, None] super().__init__(tris, texs, tex_pos)
def randiance(self, triangle, ret_power, ray_history): vnorm = triangle.norm.end.data - triangle.norm.start.data vector2 = triangle.p1.data - triangle.p2.data np.cross(vnorm, vector2) random1 = np.random.random() random2 = np.random.random() NewRay = np.cos(2 * np.pi * random1) * np.sqrt(random1) * vector2 + \ np.sin(2 * np.pi * random2) * np.sqrt(random2) * np.cross(vnorm, vector2) + \ np.sqrt(1 - random2) * vnorm x, y, z = sphere_sampling(1) newray = Vector( NewRay, Point3D( NewRay.data[0] + x, NewRay.data[1] + y, NewRay.data[2] + z, )) for i in range(len(ray_history)): if np.abs(np.dot(NewRay, NewRay)) > 1 - 1e-6: ret_power = ret_power + 1 return newray, ret_power
def __init__(self, center=Point3D.origin(), half_size=0.25): super().__init__() self.center = center self.half_size = half_size
''' debug:print the faces of the object ''' def print_obj(faces): i=0 for f in faces: i=i+1 print("face",i) print_face(f) ''' if __name__ == '__main__': point_test_1 = Point3D(4, 4, 4) point_test_2 = Point3D(4, 4,0) point_test_3 = Point3D(4, 0, 4) point_test_4 = Point3D(4, 0, 0) point_test_5 = Point3D(0, 4, 4) point_test_6 = Point3D(0, 4, 0) point_test_7 = Point3D(0, 0, 4) point_test_8 = Point3D(0, 0, 0) face_test_1 = Face([point_test_1, point_test_2, point_test_3, point_test_4]) face_test_2 = Face([point_test_1, point_test_5, point_test_6, point_test_2]) face_test_3 = Face([point_test_1, point_test_5, point_test_7, point_test_3]) face_test_4 = Face([point_test_3, point_test_4, point_test_8, point_test_7]) face_test_5 = Face([point_test_5, point_test_6, point_test_8, point_test_7]) face_test_6 = Face([point_test_2, point_test_4, point_test_8, point_test_6]) faces_test=[face_test_1,face_test_2,face_test_3,face_test_4,face_test_5,face_test_6] print_obj(DOO_Sabin(faces_test,6))