예제 #1
0
    def random_in_unit_disk(self):
        while True:
            p = Vec3(random.random(), random.random(), 0) * 2.0 - Vec3(1, 1, 0)
            if (p.dot(p) < 1.0):
                break

        return p
예제 #2
0
	def readObj(self, path):
		with open(path, "rt") as file:
			for line in file:
				if line.startswith("v "):
					info = line.split()
					self.vertices.append(Vec3(float(info[1]), float(info[2]), float(info[3])))
				elif line.startswith("vt "):
					info = line.split()
					self.tex_coords.append(Vec3(float(info[1]), float(info[2]), 0.0))
					self.has_tex_coords = True
				elif line.startswith("vn "):
					info = line.split()
					self.normals.append(Vec3(float(info[1]), float(info[2]), float(info[3])))
					self.has_normals = True
				elif line.startswith("f "):
					info = line.split()
					indices_of_vertices_of_face = []
					for i in info:
						if i != "f":
							vertex_data = []
							for j in i.split("/"):
								if j == '':
									vertex_data.append('')
								else:
									vertex_data.append(int(j) - 1)
							indices_of_vertices_of_face.append(vertex_data)
					self.faces.append(indices_of_vertices_of_face)
				elif line.startswith("o"):
					info = line.split()
					self.name = info[1]
				else:
					continue
예제 #3
0
def color(r, world, depth):
    """Get colour for:

    r      ray of interest
    world  set of hitable objects
    depth  max interaction count

    Returns colour as Vec3.
    """

    rec = Hit_Record()
    if world.hit(r, 0.001, MAXFLOAT, rec):
        #
        print('rec=%s' % str(rec))
        sys.stdout.flush()
        #
        scattered = Ray()
        attenuation = Vec3()
        if depth < 50.0 and rec.mat_ptr.scatter(r, rec, attenuation,
                                                scattered):
            print('depth=%s' % str(depth))
            return attenuation * color(scattered, world, depth + 1)

        return Vec3(0, 0, 0)
    else:
        unit_direction = r.direction.unit_vector
        t = 0.5 * (unit_direction.y + 1.0)
        return Vec3(1, 1, 1) * (1.0 - t) + Vec3(0.5, 0.7, 1.0) * t
예제 #4
0
def main():
    with open("output2.ppm", "w") as f:
        nx, ny, ns = 200, 100, 100
        header = "P3\n{} {}\n255\n".format(nx, ny)
        f.write(header)

        sphere1 = Sphere(Vec3(0, 0, -1), 0.5)
        sphere2 = Sphere(Vec3(0, -100.5, -1), 100)
        world = Hitable_list([sphere1, sphere2])

        for j in range(ny - 1, -1, -1):
            for i in range(0, nx):

                col = Vec3(0, 0, 0)
                for s in range(ns):
                    u = float(i + random()) / float(nx)
                    v = float(j + random()) / float(ny)
                    ray = Camera().get_ray(u, v)
                    col += color(ray, world)

                col /= ns
                col = Vec3(sqrt(col.r()), sqrt(col.g()), sqrt(col.b()))
                ir = int(255.99 * col.r())
                ig = int(255.99 * col.g())
                ib = int(255.99 * col.b())
                line = "{} {} {}\n".format(ir, ig, ib)
                f.write(line)
예제 #5
0
def cornell_smoke():
    '''Generate a scene with a Cornell box where the boxes are filled with smoke'''
    world = HittableList()

    red = Lambertian(Color(0.65, 0.05, 0.05))
    white = Lambertian(Color(0.73, 0.73, 0.73))
    green = Lambertian(Color(0.12, 0.45, 0.15))
    light = DiffuseLight(Color(7, 7, 7))

    box1 = Box(Point3(0, 0, 0), Point3(165, 330, 165), white)
    box1 = RotateY(box1, 15)
    box1 = Translate(box1, Vec3(265, 0, 295))

    box2 = Box(Point3(0, 0, 0), Point3(165, 165, 165), white)
    box2 = RotateY(box2, -18)
    box2 = Translate(box2, Vec3(130, 0, 65))

    world.add(yzRect(0, 555, 0, 555, 555, green))
    world.add(yzRect(0, 555, 0, 555, 0, red))
    world.add(xzRect(0, 555, 0, 555, 555, white))
    world.add(xzRect(0, 555, 0, 555, 0, white))
    world.add(xyRect(0, 555, 0, 555, 555, white))

    world.add(ConstantMedium(box1, 0.01, Color(0, 0, 0)))
    world.add(ConstantMedium(box2, 0.01, Color(1, 1, 1)))

    world.add(xzRect(113, 443, 127, 432, 554, light))

    return world
예제 #6
0
def blue_to_white(i, j, nx, ny):
    r = origin_to_pixel(i, j, nx, ny)
    v = r.direction().unit_vector(
    )  # use y-coordinate of unit direction to scale blueness
    t = (v.y() + 1) / 2  # ranges between 0 and 1
    return Vec3(255.99, 255.99, 255.99) * (1 - t) + Vec3(
        255.99 * 0.5, 255.99 * 0.7, 255.99) * t
예제 #7
0
def diffuse_sphere(i, j, nx, ny, num_samples=100):
    s1 = Sphere(Vec3(-0.75, 0.75, -1), 0.5, Lambertian(Vec3(0.8, 0.3, 0.3)))
    s2 = Sphere(Vec3(0, -100.5, -1), 100, Lambertian(Vec3(0.2, 0.6, 0.2)))
    spheres = HitableList([s1, s2])
    cam = Camera()

    def color(r, world):
        if world.hit(r, 0.001, float("inf")):
            scattered, attenuation = world.matrl.scatter(
                r, world.p, world.normal)
            if scattered:
                return color(scattered, world) * attenuation
            else:
                return Vec3(0, 0, 0)
        else:
            v = r.direction().unit_vector(
            )  # use y-coordinate of unit direction to scale blueness
            t = (v.y() + 1) / 2  # ranges between 0 and 1
            return Vec3(255.99, 255.99, 255.99) * (1 - t) + Vec3(
                255.99 * 0.5, 255.99 * 0.7, 255.99) * t

    col = Vec3(0, 0, 0)
    for k in range(num_samples):
        col += color(
            cam.get_ray((i + random.random()) / nx,
                        (j + random.random()) / ny), spheres)

    return col / num_samples
예제 #8
0
def test_finte():
    q1 = Quat(10000000000, 210000000000, 310000000000, -2147483647)
    q2 = Quat(np.nan, 210000000000, 310000000000, -2147483647)
    q3 = Quat(np.inf, 210000000000, 310000000000, -2147483647)
    q4 = Quat(0.0, 210000000000, np.NINF, -2147483647)

    v1 = Vec3(10000000000, 210000000000, 310000000000)
    v2 = Vec3(np.nan, 210000000000, 310000000000)
    v3 = Vec3(np.inf, 210000000000, 310000000000)
    v4 = Vec3(0.0, 210000000000, np.NINF)

    t1 = Transform(q1, v1)
    assert t1.is_finite()
    assert not t1.is_nan()

    t2 = Transform(q1, v2)
    assert not t2.is_finite()
    assert t2.is_nan()

    t3 = Transform(q3, v1)
    assert not t3.is_finite()
    assert t3.is_nan()

    t4 = Transform(q4, v4)
    assert not t4.is_finite()
    assert t4.is_nan()
 def scatter(self, r_in, rec):
   outward_normal = Vec3()
   reflected = Vec3.reflect(r_in.direction,rec["normal"])
   ni_over_nt = 0.0
   attenuation = Vec3(1.0,1.0,1.0)
   cosine = 0.0
   if Vec3.dot(r_in.direction,rec["normal"]) > 0:
     outward_normal = -rec["normal"]
     ni_over_nt = self.ref_idx
     cosine = self.ref_idx * Vec3.dot(r_in.direction,rec["normal"])/ r_in.direction.length()
   else:
     outward_normal = rec["normal"]
     ni_over_nt = 1.0 / self.ref_idx
     cosine = -Vec3.dot(r_in.direction,rec["normal"])/ r_in.direction.length()
   
   scattered = Ray()
   reflect_prob = 0.0
   refracted = Vec3.refract(r_in.direction,outward_normal,ni_over_nt)
   if refracted is not None:
     reflect_prob = schlick(cosine,self.ref_idx)
   else:
     reflect_prob = 1.0
   if random() < reflect_prob:
     scattered = Ray(rec["p"],reflected)
   else:
     scattered = Ray(rec["p"],refracted)
   return attenuation, scattered
예제 #10
0
def colored_sphere(i, j, nx, ny):
    s = Sphere(Vec3(0, 0, -1), 0.5)
    r = origin_to_pixel(i, j, nx, ny)
    if s.hit(r, 0, float("inf")):
        return (s.normal + Vec3(1, 1, 1)) * 255.99 / 2
    else:
        return blue_to_white(i, j, nx, ny)
예제 #11
0
 def get_plane(self, sp1, sp2, sp3, dist_21, dist_23, ang_13):
     """ Returns the plane object defined by three points projected onto some unknown perspective.
     :param sp1: screen point 1
     :param sp2: screen point 2
     :param sp3: screen point 3
     :param dist_21: real distance from 2 to 1
     :param dist_23: real distance from 2 to 3
     :param ang_13: angle between vectors sp1-sp2 and sp2-sp3
     :return: plane in real coordinates
     """
     l01 = self.line(sp1)
     l02 = self.line(sp2)
     l03 = self.line(sp3)
     param = 0
     a = l02.get_point(param)
     t1 = l01.get_point_at_dist(a, dist_21, line.Direction.POSITIVE)
     t3 = l03.get_point_at_dist(a, dist_23, line.Direction.POSITIVE)
     ang = Vec3.angle_between(t1 - a, t3 - a)
     while abs(ang - ang_13) > 0.001:
         param += 10.0 * abs(ang - ang_13)
         while True:
             a = l02.get_point(param)
             try:
                 t1 = l01.get_point_at_dist(a, dist_21, line.Direction.POSITIVE)
                 t3 = l03.get_point_at_dist(a, dist_23, line.Direction.POSITIVE)
                 break
             except ValueError:
                 param -= 0.1 * abs(ang - ang_13)
         ang = Vec3.angle_between(t1 - a, t3 - a)
         i = inspect.getframeinfo(inspect.currentframe())
     return Plane(a, t1 - a, t3 - a)
예제 #12
0
def test_rotate_vec():
    v = Vec3(1, 1, 0)

    q1 = Quat.from_rotation_on_axis(0, np.pi / 3)
    q2 = Quat.from_rotation_on_axis(1, np.pi / 3)
    q3 = Quat.from_rotation_on_axis(2, np.pi / 3)

    # forward rotation
    v1 = q1.rotate(v)
    v2 = q2.rotate(v)
    v3 = q3.rotate(v)

    theta1 = (60) * np.pi / 180.0
    v1_true = Vec3(1, math.cos(theta1), math.sin(theta1))
    v2_true = Vec3(math.cos(theta1), 1, -math.sin(theta1))

    theta2 = (45 + 60) * np.pi / 180.0
    v3_true = math.sqrt(2) * Vec3(math.cos(theta2), math.sin(theta2), 0)

    assert v1 == v1_true
    assert v2 == v2_true
    assert v3 == v3_true

    # inverse rotate
    v1_rev = q1.inverse_rotate(v1_true)
    v2_rev = q2.inverse_rotate(v2_true)
    v3_rev = q3.inverse_rotate(v3_true)

    assert v == v1_rev
    assert v == v2_rev
    assert v == v3_rev
예제 #13
0
def random_in_unit_sphere_3():
    """Get a random vector inside the 3d unit sphere."""

    while True:
        p = Vec3(random(), random(), random()) * 2.0 - Vec3(1, 1, 1)
        if p.squared_length < 1.0:
            return p
예제 #14
0
    def scatter(self, r_in, rec, attenuation, scattered):
        reflected = reflect(r_in.direction, rec.normal)
        attenuation = Vec3(1, 1, 1)
        refracted = Vec3()
        if r_in.direction.dot(rec.normal) > 0.0:
            outward_normal = -rec.normal
            ni_over_nt = self.ref_idx
            cosine = r_in.direction.dot(rec.normal) / r_in.direction.length
            cosine = sqrt(1.0 - self.ref_idx * self.ref_idx *
                          (1.0 - cosine * cosine))
        else:
            outward_normal = rec.normal
            ni_over_nt = 1.0 / self.ref_idx
            cosine = -r_in.direction.dot(rec.normal) / r_in.direction.length

        if refract(r_in.direction, outward_normal, ni_over_nt, refracted):
            reflect_prob = schlick(cosine, self.ref_idx)
        else:
            reflect_prob = 1.0

        if random() < reflect_prob:
            scattered.update(rec.p, reflected)
        else:
            scattered.update(rec.p, refracted)

        return True
예제 #15
0
def main():
    # G = 1
    # M1 = 1
    # M2 = 1
    R = 1
    v = math.sqrt(1 / (4 * R))
    r1 = Vec3(-R, 0, 0)
    r2 = Vec3(R, 0, 0)
    v1 = Vec3(0, -v, 0)
    v2 = Vec3(0, v, 0)
    time_step = 0.01
    r1_data, r2_data = [], []
    n_steps = 100000
    for i in range(n_steps + 1):
        r1_data.append(r1)
        r2_data.append(r2)
        r1, r2, v1, v2 = leapfrog(r1, r2, v1, v2, time_step)
        # print("\rcalculation progress: t = {:.2f} / {:.2f} ({:.2f}%)".format(i * time_step, n_steps * time_step,
        #                                                                      100 * i / n_steps),
        #       end="")
        print(runge(r1, v1))
        print(runge(r2, v2))
    x1_data = [p.x for p in r1_data]
    y1_data = [p.y for p in r1_data]
    x2_data = [p.x for p in r2_data]
    y2_data = [p.y for p in r2_data]
    plt.figure(figsize=(8, 8))
    plt.plot(x1_data, y1_data)
    plt.plot(x2_data, y2_data)
    plt.xlim(-5, 5)
    plt.ylim(-5, 5)
    plt.show()
예제 #16
0
    def __init__(self,
                 look_from: Vec3 = Vec3(3.0, 3.0, 2.0),
                 look_at: Vec3 = Vec3(0.0, 0.0, -1.0),
                 vec_up: Vec3 = Vec3(0.0, 1.0, 0.0),
                 v_fov: float = 90.0,
                 aspect: float = 1.0,
                 aperture: float = 0.0,
                 focus_dist: float = 1.0):

        self.lens_radius = aperture / 2.0

        theta = v_fov * 3.14159 / 180.0
        half_height = math.tan(theta / 2.0)
        half_width = aspect * half_height

        w = unit_vector(look_from - look_at)
        self.u = unit_vector(vec_up.cross(w))
        self.v = w.cross(self.u)

        self.origin = look_from
        self.upper_left_corner = look_from - \
                                 half_width*self.u*focus_dist + \
                                 half_height*self.v*focus_dist - w*focus_dist
        self.horizontal = 2 * half_width * self.u * focus_dist
        self.vertical = -2 * half_height * self.v * focus_dist
def two_spheres():
    l = []
    checker = CheckerTexture(ConstantTexture(Vec3(0.2, 0.3, 0.1)),
                             ConstantTexture(Vec3(0.9, 0.9, 0.9)))
    l.append(Sphere(Vec3(0.0, -10.0, 0.0), 10, Lambertian(checker)))
    l.append(Sphere(Vec3(0.0, 10.0, 0.0), 10, Lambertian(checker)))
    return HitableList(l)
예제 #18
0
def random_in_unit_disk_2():
    """Get a random vector inside the unit sphere."""

    while True:
        p = Vec3(random(), random(), 0) * 2.0 - Vec3(1, 1, 0)
        if p.dot(p) < 1.0:
            return p
예제 #19
0
def main():

    nx = 200
    ny = 100
    ns = 30

    f = open("generated_images/first_world.ppm","w")
    f.write("P3\n%d %d\n255\n"%(nx,ny))

    cam = Camera()

    world = Object3DList(
            [Sphere(Vec3(0.0,0.0,-1.0), 0.5),
             Sphere(Vec3(0.0,-100.5,-1.0),100)])

    # Note break with guide convention, vertical pixels start with index 0 at top
    for y in range(0,ny):
        for x in range(0,nx):
            col = Vec3(0.0,0.0,0.0)
            for _ in range(0, ns):
                u = (float(x)+random.random())/float(nx)
                v = (float(y)+random.random())/float(ny)
                r = cam.get_ray(u, v)
                col += color(r, world)

            col /= ns

            f.write(col.color_string(scale=255.99))

    f.close()
예제 #20
0
    def scatter(self, ray, rec, srec):
        srec.is_specular = True
        srec.pdf_ptr = 0
        srec.attenuation = Vec3(1.0, 1.0, 1.0)
        outward_normal = Vec3()
        reflected = ray.dir.reflect(rec.normal)
        refracted = Vec3()

        if ray.dir.dot(rec.normal) > 0:
            outward_normal = -rec.normal
            ni_over_nt = self.ref_idx
            cosine = self.ref_idx * ray.dir.dot(rec.normal) / ray.dir.length()
        else:
            outward_normal = rec.normal
            ni_over_nt = 1.0 / self.ref_idx
            cosine = -ray.dir.dot(rec.normal) / ray.dir.length()

        if self.refract(ray.dir, outward_normal, ni_over_nt, refracted):
            reflect_prob = self.schlick(cosine, self.ref_idx)
        else:
            reflect_prob = 1.0

        if random() < reflect_prob:
            srec.specular_ray = Ray(rec.p, reflected)
        else:
            srec.specular_ray = Ray(rec.p, refracted)
        return True
예제 #21
0
def getSegmentsFromIntersections( solidXIntersectionList, y, z ):
	"Get endpoint segments from the intersections."
	segments = []
	xIntersectionList = []
	fill = False
	solid = False
	solidTable = {}
	solidXIntersectionList.sort( compareSolidXByX )
	for solidX in solidXIntersectionList:
		solidXYInteger = int( solidX.imag )
		if solidXYInteger >= 0:
			toggleHashtable( solidTable, solidXYInteger, "" )
		else:
			fill = not fill
		oldSolid = solid
		solid = ( len( solidTable ) == 0 and fill )
		if oldSolid != solid:
			xIntersectionList.append( solidX.real )
	for xIntersectionIndex in range( 0, len( xIntersectionList ), 2 ):
		firstX = xIntersectionList[ xIntersectionIndex ]
		secondX = xIntersectionList[ xIntersectionIndex + 1 ]
		endpointFirst = Endpoint()
		endpointSecond = Endpoint().getFromOtherPoint( endpointFirst, Vec3( secondX, y, z ) )
		endpointFirst.getFromOtherPoint( endpointSecond, Vec3( firstX, y, z ) )
		segment = ( endpointFirst, endpointSecond )
		segments.append( segment )
	return segments
예제 #22
0
파일: main.py 프로젝트: candyer/Ray-tracing
def main():
    with open("output.ppm", "w") as f:
        nx, ny, ns = 200, 100, 100
        header = "P3\n{} {}\n255\n".format(nx, ny)
        f.write(header)

        camera = Camera()
        sphere1 = Sphere(Vec3(0.0, 0.0, -1.0), 0.5,
                         Lambertian(Vec3(0.8, 0.3, 0.3)))
        sphere2 = Sphere(Vec3(0.0, -100.5, -1.0), 100.0,
                         Lambertian(Vec3(0.8, 0.8, 0.0)))
        sphere3 = Sphere(Vec3(1.0, 0.0, -1.0), 0.5, Metal(Vec3(0.8, 0.6, 0.2)))
        sphere4 = Sphere(Vec3(-1.0, 0.0, -1.0), 0.5, Metal(Vec3(0.8, 0.8,
                                                                0.8)))

        world = Hitable_list([sphere1, sphere2, sphere3, sphere4])
        for j in range(ny - 1, -1, -1):
            for i in range(nx):
                col = Vec3(0.0, 0.0, 0.0)
                for k in range(0, ns):
                    u = float(i + random()) / float(nx)
                    v = float(j + random()) / float(ny)
                    ray = camera.get_ray(u, v)
                    col += color(ray, world, 0)

                col /= float(ns)
                col = Vec3(sqrt(col.e0), sqrt(col.e1), sqrt(col.e2))
                ir = int(255.99 * col.r())
                ig = int(255.99 * col.g())
                ib = int(255.99 * col.b())
                line = "{} {} {}\n".format(ir, ig, ib)
                f.write(line)
예제 #23
0
def cornell_box():
    '''Generate a scene with a Cornell box, using rectangles and boxes'''
    world = HittableList()

    red = Lambertian(Color(0.65, 0.05, 0.05))
    white = Lambertian(Color(0.73, 0.73, 0.73))
    green = Lambertian(Color(0.12, 0.45, 0.15))
    light = DiffuseLight(Color(15, 15, 15))
    aluminum = Metal(Color(0.8, 0.85, 0.88), 0.0)
    glass = Dielectric(1.5)

    box1 = Box(Point3(0, 0, 0), Point3(165, 330, 165), aluminum)
    box1 = RotateY(box1, 15)
    box1 = Translate(box1, Vec3(265, 0, 295))

    box2 = Box(Point3(0, 0, 0), Point3(165, 165, 165), white)
    box2 = RotateY(box2, -18)
    box2 = Translate(box2, Vec3(130, 0, 65))

    world.add(yzRect(0, 555, 0, 555, 555, green))
    world.add(yzRect(0, 555, 0, 555, 0, red))
    world.add(xzRect(0, 555, 0, 555, 555, white))
    world.add(xzRect(0, 555, 0, 555, 0, white))
    world.add(xyRect(0, 555, 0, 555, 555, white))

    world.add(box1)
    world.add(box2)

    world.add(FlipFace(xzRect(213, 343, 227, 332, 554, light)))

    return world
def hit_sphere(center,radius,r):
  oc = r.origin -center
  a = Vec3.dot(r.direction,r.direction)
  b = 2.0 * Vec3.dot(oc,r.direction)
  c = Vec3.dot(oc,oc) - radius * radius
  discriminant = b*b - 4*a*c
  return discriminant > 0
예제 #25
0
 def hit(self,r,t_min,t_max):
   rec = None
   oc = r.origin - self.center(r.time)
   a = Vec3.dot(r.direction,r.direction)
   b = Vec3.dot(oc,r.direction)
   c = Vec3.dot(oc,oc) - (self.radius*self.radius)
   discriminant = (b*b) - (a*c)
   if discriminant > 0:
     rec = {}
     temp = (-b - sqrt(discriminant)) / a
     if t_min < temp < t_max:
       rec["t"] = temp
       rec["p"] = r.point_at_parameter(rec["t"])
       rec["u"],rec["v"] =getSphereUv((rec["p"] - self.center) / self.radius)
       rec["normal"] = (rec["p"] - self.center(r.time)) / self.radius
       rec["material"] = self.material
       return rec
     temp = (-b + sqrt(discriminant)) / a
     if t_min < temp < t_max:
       rec["t"] = temp
       rec["p"] = r.point_at_parameter(rec["t"])
       rec["u"],rec["v"] =getSphereUv((rec["p"] - self.center) / self.radius)
       rec["normal"] = (rec["p"] - self.center(r.time)) / self.radius
       rec["material"] = self.material
       return rec
   return None
예제 #26
0
def random_in_unit_sphere():
    """Return a random vector in the unit sphere."""

    while True:
        p = Vec3(random(), random(), random()) * 2.0 - Vec3(1.0, 1.0, 1.0)
        if p.squared_length < 1.0:
            return p
예제 #27
0
    def __init__(self):
        """A camera clas."""

        self.origin = Vec3(0.0, 0.0, 0.0)
        self.lower_left_corner = Vec3(-2.0, -1.0, -1.0)
        self.horizontal = Vec3(4.0, 0.0, 0.0)
        self.vertical = Vec3(0.0, 2.0, 0.0)
예제 #28
0
파일: vec3_test.py 프로젝트: dxyang/math3d
def test_dot():
    v1 = Vec3(0, 1, 2)
    v2 = Vec3(3, 4, 5)

    res = v1.dot(v2)

    assert res == 14
예제 #29
0
 def __init__(self, h):
     nz = cos(radians(h))
     nx = sqrt(1 - nz * nz)
     height = nz / nx
     #print(nx, nz, height)
     self.lside = Plane(Vec3(0.0, 0.0, -height), Vec3(nx, 0.0, nz))
     self.rside = Plane(Vec3(0.0, 0.0, -height), Vec3(-nx, 0.0, nz))
예제 #30
0
    def __init__(self):

        self.position = Vec3()
        self.normal = Vec3()

        self.t = 0.0
        self.frontFacing = False
예제 #31
0
def random_in_unit_sphere():
    #    p = Vec3(0, 0, 0)
    while True:
        p = Vec3(random(), random(), random()) * 2.0 - Vec3(1.0, 1.0, 1.0)
        if p.squared_length < 1.0:
            break
    return p
def main():
    nx = 200
    ny = 150
    ns = 100
    print("P3\n", nx, " ", ny, "\n255")

    world = two_spheres()

    lookfrom = Vec3(13, 2, 3)
    lookat = Vec3(0, 0, 0)
    dist_to_focus = 10.0
    aperture = 0.0
    cam = Camera(lookfrom, lookat, Vec3(0, 1, 0), 20, nx / ny, aperture,
                 dist_to_focus, 0.0, 1.0)
    for j in reversed(range(ny)):
        for i in range(nx):
            col = Vec3(0, 0, 0)
            for s in range(ns):
                u = (i + random()) / nx
                v = (j + random()) / ny
                r = cam.get_ray(u, v)
                p = r.point_at_parameter(2.0)
                col += color(r, world, 0)

            col /= ns
            col = Vec3(sqrt(col[0]), sqrt(col[1]), sqrt(col[2]))
            ir = int(255.99 * col[0])
            ig = int(255.99 * col[1])
            ib = int(255.99 * col[2])
            print(ir, " ", ig, " ", ib)
예제 #33
0
 def scatter(self, r_in,rec):
   reflected = Vec3.reflect(Vec3.unit_vector(r_in.direction),rec["normal"])
   scattered = Ray(rec["p"],reflected + self.fuzz * Material.random_in_unit_sphere())
   attenuation = self.albedo
   if Vec3.dot(scattered.direction,rec["normal"]) > 0:
     return attenuation,scattered
   else:
     return None,None
예제 #34
0
def color(ray):
    t = hit_sphere(Vec3(0, 0, -1), 0.5, ray)
    if t > 0.0:
        N = (ray.point_at_parameter(t) - Vec3(0, 0, -1)).unit_vector()
        return Vec3(N.x() + 1, N.y() + 1, N.z() + 1) * 0.5
    unit_direction = ray.direction.unit_vector()
    t = 0.5 * (unit_direction.y() + 1.0)
    return Vec3(1.0, 1.0, 1.0) * (1.0 - t) + Vec3(0.5, 0.7, 1.0) * t
예제 #35
0
 def __init__(self,lookfrom,lookat,vup,vfov,aspect,aperture,focus_dist):
   self.lens_radius = aperture /2
   theta = vfov * math.pi/180
   half_height = math.tan(theta/2)
   half_width = aspect * half_height
   self.origin = lookfrom
   self.w = Vec3.unit_vector(lookfrom -lookat)
   self.u = Vec3.unit_vector(Vec3.cross(vup,self.w))
   self.v = Vec3.cross(self.w,self.u)
   self.lower_left_corner = self.origin - half_width*focus_dist*self.u -half_height*focus_dist*self.v -focus_dist*self.w
   self.horizontal = 2*half_width*focus_dist*self.u
   self.vertical = 2*half_height*focus_dist*self.v
def color(r,world):
  rec = world.hit(r,0.0,float('inf'))
  if rec is not None:
    target = rec["p"]+rec["normal"] + random_in_unit_sphere()
    return 0.5 * color(Ray(rec["p"],target-rec["p"]),world)
  else:
    unit_direction = Vec3.unit_vector(r.direction)
    t = 0.5*(unit_direction.y +1.0)
    return (1.0-t)*Vec3(1.0,1.0,1.0) + t*Vec3(0.5,0.7,1.0)
예제 #37
0
 def hit(self,r,t_min,t_max):
   rec = None
   oc = r.origin - self.center
   a = Vec3.dot(r.direction,r.direction)
   b = Vec3.dot(oc,r.direction)
   c = Vec3.dot(oc,oc) - (self.radius*self.radius)
   discriminant = (b*b) - (a*c)
   if discriminant > 0:
     rec = {}
     temp = (-b - sqrt(discriminant)) / a
     if t_min < temp < t_max:
       rec["t"] = temp
       rec["p"] = r.point_at_parameter(rec["t"])
       rec["normal"] = (rec["p"] - self.center) / self.radius
       return rec
     temp = (-b + sqrt(discriminant)) / a
     if t_min < temp < t_max:
       rec["t"] = temp
       rec["p"] = r.point_at_parameter(rec["t"])
       rec["normal"] = (rec["p"] - self.center) / self.radius
       return rec
   return None
def color(r,world,depth):
  rec = world.hit(r,0.001,float('inf'))
  if rec is not None:
    if depth >= 50:
      return Vec3(0,0,0)
    attenuation,scattered =rec["material"].scatter(r,rec)
    if attenuation is not None:
      return attenuation * color(scattered,world,depth +1)
    else:
      return Vec3(0,0,0)
  else:
    unit_direction = Vec3.unit_vector(r.direction)
    t = 0.5*(unit_direction.y +1.0)
    return (1.0-t)*Vec3(1.0,1.0,1.0) + t*Vec3(0.5,0.7,1.0)
def color(r):
  unit_direction = Vec3.unit_vector(r.direction)
  t = 0.5*(unit_direction.y +1.0)
  return (1.0-t)*Vec3(1.0,1.0,1.0) + t*Vec3(0.5,0.7,1.0)
예제 #40
0
 def get_dist_to_point(self, point):
     return abs(Vec3.from_to(point, self.get_closest_point_to(point)))
예제 #41
0
 def get_closest_point_to(self, point):
     n = self.get_normal()
     return point - (Vec3.dot(Vec3.from_to(self.origin, point), n)*n)
예제 #42
0
 def get_normal(self):
     return Vec3.cross(self.direction1, self.direction2).get_unit()
예제 #43
0
 def random_in_unit_sphere(cls):
   while True:
     p = 2.0*Vec3(random(),random(),random()) - Vec3(1,1,1)
     if Vec3.dot(p,p) < 1.0:
       return p
예제 #44
0
def random_in_unit_disk():
  while True:
    p = 2.0 * Vec3(random(),random(),0) -Vec3(1,1,0)
    if Vec3.dot(p,p) < 1.0:
      return p
def color(r):
  if hit_sphere(Vec3(0,0,-1),0.5,r):
    return Vec3(1,0,0)
  unit_direction = Vec3.unit_vector(r.direction)
  t = 0.5*(unit_direction.y +1.0)
  return (1.0-t)*Vec3(1.0,1.0,1.0) + t*Vec3(0.5,0.7,1.0)
예제 #46
0
 def get_closest_point_to(self, point):
     l = self.direction.get_unit()
     return self.origin + (Vec3.dot(Vec3.from_to(self.origin, point), l)*l)