From 66bc98e7a4c1ea6e80f442e146a8eb1e10e01b21 Mon Sep 17 00:00:00 2001
From: Benjamin Koltes <benjamin.koltes@student.ecp.fr>
Date: Wed, 23 Mar 2016 14:50:09 +0100
Subject: [PATCH] yolo

---
 reflection.py                     |  26 ++++++++++++++++++++++++++
 scenes/reflection.py              |   5 +++--
 scenes/two_spheres_reflection.png | Bin 2167 -> 2582 bytes
 tests/02_rayon.py                 |   3 +--
 two_spheres_reflection.png        | Bin 0 -> 9339 bytes
 5 files changed, 30 insertions(+), 4 deletions(-)
 create mode 100644 reflection.py
 create mode 100644 two_spheres_reflection.png

diff --git a/reflection.py b/reflection.py
new file mode 100644
index 0000000..bdb61f9
--- /dev/null
+++ b/reflection.py
@@ -0,0 +1,26 @@
+# Show to python where to find the modules
+from scene import *
+from light import Spotlight
+from camera import Camera
+from raytracer import raytracer_render
+from matplotlib.image import imsave
+
+camera = Camera(600,600,1)
+materiau_sphere_bleue = Material(Vector((0,0,1)), .5, .3, .3, 100, .5)
+materiau_sphere_rouge = Material(Vector((1,0,0)), .5, .3, .3, 100, .3)
+materiau_sphere_blanche = Material(Vector((1,1,1)), .5, .3, .3, 100, .7)
+materiau_sphere_verte= Material(Vector((0,1,0)), .5, .3, .3, 100, .3)
+sphere_bleue = Sphere(Vector([0,0,3]), .8, materiau_sphere_bleue)
+sphere_rouge = Sphere(Vector([0.5,0.5,2]), .5, materiau_sphere_rouge)
+sphere_blanche = Sphere(Vector([0,0,0]), 50, materiau_sphere_blanche)
+sphere_verte = Sphere(Vector([2,-2,3]), .5, materiau_sphere_verte)
+lumiere = Spotlight(Vector((1,1,0)), Vector((1,1,1)))
+scene = Scene()
+scene.add_object(sphere_bleue)
+scene.add_object(sphere_rouge)
+scene.add_object(sphere_blanche)
+scene.add_object(sphere_verte)
+scene.add_light(lumiere)
+affiche = raytracer_render(camera, scene)
+imsave('two_spheres_reflection.png',affiche)
+print('Done')
diff --git a/scenes/reflection.py b/scenes/reflection.py
index cde3e1b..694f636 100644
--- a/scenes/reflection.py
+++ b/scenes/reflection.py
@@ -10,8 +10,8 @@ from matplotlib.image import imsave
 import sys
 
 camera = Camera(200,200,1)
-materiau_sphere_bleue = Material(Vector((0,0,1)), .7, .7, .7, 100, .7)
-materiau_sphere_rouge = Material(Vector((1,0,0)), .7, .7, .7, 100, .7)
+materiau_sphere_bleue = Material(Vector((0,0,1)), .5, .3, .3, 100, .5)
+materiau_sphere_rouge = Material(Vector((1,0,0)), .5, .3, .3, 100, .3)
 sphere_bleue = Sphere(Vector([0,0,3]), .8, materiau_sphere_bleue)
 sphere_rouge = Sphere(Vector([0.5,0.5,2]), .5, materiau_sphere_rouge)
 lumiere = Spotlight(Vector((1,1,0)), Vector((1,1,1)))
@@ -21,3 +21,4 @@ scene.add_object(sphere_rouge)
 scene.add_light(lumiere)
 affiche = raytracer_render(camera, scene)
 imsave('two_spheres_reflection.png',affiche)
+print('Done')
diff --git a/scenes/two_spheres_reflection.png b/scenes/two_spheres_reflection.png
index 3345277b857a806c034bb22e1094bef0573fbc05..196361e20de713ac5dc8d7c1f2cb55ff4706606a 100644
GIT binary patch
literal 2582
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

literal 2167
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
FngH+czeE54

diff --git a/tests/02_rayon.py b/tests/02_rayon.py
index 1ce0c2f..d3389e7 100644
--- a/tests/02_rayon.py
+++ b/tests/02_rayon.py
@@ -25,7 +25,6 @@ r_one = c.ray_at(c.image_nrows, c.image_ncols);
 r_one_ref_dir = Vector([-1,-1,c.focal_length])
 r_one_ref_dir = r_one_ref_dir / r_one_ref_dir.norm()
 
-assert abs(r_one.direction*(r_one_ref_dir) -
-           r_one.direction.norm() < 0.01), "c.ray_at(c.nrows,c.ncols) should have the direction [-1,-1,c.focal_length.";
+assert abs(r_one.direction*(r_one_ref_dir) - r_one.direction.norm()) < 0.01, "c.ray_at(c.nrows,c.ncols) should have the direction [-1,-1,c.focal_length.";
 
 
diff --git a/two_spheres_reflection.png b/two_spheres_reflection.png
new file mode 100644
index 0000000000000000000000000000000000000000..89fa5b3d0f4ce9c9ebddff669a4909cf3cf51d8d
GIT binary patch
literal 9339
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
WVm~q`#4|83FnGH9xvX<aXaWEL->Rwr

literal 0
HcmV?d00001

-- 
GitLab