From 14c2402d3a14e1947f8852fe692b45344a781e35 Mon Sep 17 00:00:00 2001 From: Benjamin Koltes <benjamin.koltes@student.ecp.fr> Date: Sun, 20 Mar 2016 20:51:55 +0100 Subject: [PATCH] fix de light.py et ajout des tests --- __pycache__/camera.cpython-33.pyc | Bin 0 -> 1100 bytes __pycache__/intersection.cpython-33.pyc | Bin 0 -> 1765 bytes __pycache__/light.cpython-33.pyc | Bin 0 -> 1651 bytes __pycache__/operation_vector.cpython-33.pyc | Bin 0 -> 7404 bytes __pycache__/raytracer.cpython-33.pyc | Bin 0 -> 2603 bytes __pycache__/scene.cpython-33.pyc | Bin 0 -> 2054 bytes camera.py | 3 +- light.py | 8 ++++- one_sphere.png | Bin 6168 -> 0 bytes operation_vector.py | 10 +++--- raytracer.py | 5 ++- scene.py | 3 +- script_one_sphere.py | 23 +++++++++----- tests/01_camera_ok.py | 14 +++++++++ tests/02_rayon_ok.py | 31 ++++++++++++++++++ tests/03_sphere_intersection_ok.py | 33 ++++++++++++++++++++ tests/04_material_ok.py | 14 +++++++++ tests/05_phong_ok.py | 32 +++++++++++++++++++ 18 files changed, 158 insertions(+), 18 deletions(-) create mode 100644 __pycache__/camera.cpython-33.pyc create mode 100644 __pycache__/intersection.cpython-33.pyc create mode 100644 __pycache__/light.cpython-33.pyc create mode 100644 __pycache__/operation_vector.cpython-33.pyc create mode 100644 __pycache__/raytracer.cpython-33.pyc create mode 100644 __pycache__/scene.cpython-33.pyc delete mode 100644 one_sphere.png create mode 100644 tests/01_camera_ok.py create mode 100644 tests/02_rayon_ok.py create mode 100644 tests/03_sphere_intersection_ok.py create mode 100644 tests/04_material_ok.py create mode 100644 tests/05_phong_ok.py diff --git a/__pycache__/camera.cpython-33.pyc b/__pycache__/camera.cpython-33.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ac9cd14ce80218af0287c5e0f604d59b9c1e5cf GIT binary patch literal 1100 zcmbQo!^>rJ>s{DaMh1pt1|-1Dz`)?Zz`#&!&cMKs!oZNi$dJRpkjuyr#mK-2;xjSi zFfrsZGej{nFuJEOGo-LEv@n3kW+sLx7KRj7hF}dg1_p*qkf9ok3=9mVAZ}P{a!Gy> zgb%VKD6ujbBneUlqL~;N7@R=%>M$@c)G#o(rZRx6OkrS%VgflLg$ZO$6f*<dN@UBx zRyZf-rWPe8vw)0bU|;~zAXA+|rpkj%Wds=<&%jW_1ZFTY)G&h?OdyX2gWcw*0dia^ zH^>9IiRr2Fc}4l<#mM~R{G8%a9tH-6wEX16ocNs7y!4U`4UlD}Afh-mCk<ISR_*+t zu+1zkNz6-5jR%{PssVB}m;f8Drx%k9_KsdbWhn;(14Dd#W?p7Vd^{`2H=qDzVB}=v zWGn?41@X8ZOi41x3n1e_%0L(#0x6&nU|`4sN2ydTGuZQt3=%cW4AQkMpm4}y1O+rq ziU}&k%22|@P{PcR!URR>%nZ$pAdwmth8k9|Miz!NuwXM2Lohf1{W3uz4@m+b7ZVH- zkduQFE5Y#yNh;uA0EZ1Mj6q&OgfU1*QGR(Th)&MWDFr2>JTO@SCM&^#2`0csp@b;N zsG`Km_{0(}P<Vm}21Z^+J}@rjWnf@{hABjmp9a_yka);T%uS7tF9qp|kI&6dDa`?K zdBAa0Selpvm4_&XL>kyz5Tn4U45~Q?l!A)m<H3#u6WCn}aSJ$gfd~Oc9#*i45OJvE z1Q-|?@(WUn5=%1k^Ww|E*$u1;8l0RA3=Bnyl_f=q$*D!)P=kdx#2B#s2m;e3AP?C< O{A&ja>|%&p1egFwcGMRD literal 0 HcmV?d00001 diff --git a/__pycache__/intersection.cpython-33.pyc b/__pycache__/intersection.cpython-33.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fae1ae74b367b9008f501976711328e4472c8010 GIT binary patch literal 1765 zcmbQo!^?H+`K_?sEDQ|E3`l^Pfq}t+fq|jeoPmKMg@GZ3ks*hHAq2`|WC(FjVPZ&O zW@upmk<CmDQA`XeEDR~EAdx6$h7>l2U=4N#28K+Kp&E<~3=E|pLMs_Wg2X^H69WT- z6UY_?1_p*21_swu28Jj`kbNNI7#UKSV8$^s1Z%K>4B=s5VDQW<Ni8Z)O)kmI&r1f0 zg3JTaAoH9-=E;N1V+0u)&%jW_1ZFTY)G&h?Odtz_!EW-?0C}{OgMopeAip>hWMC;9 z0|P@|eo<~>4w#vrl$DxX0<j!qM{#OS8ZjC`Zqfh|rJ!(hwu%WYPAw{qaZ1h0O3cm7 zi*d<MF3nBND?t)+&n$^aNiB=d$xn~TMDn9vK_%G6`1s7c%#!$cR*)A#&SYTZWaMNl z6-5gZJ(xm2h_gZ7i;vGs%uS7tFXdujV2F>;%}*)K0dYa$86RI*nwSHXhbV?v1P&vp zj-34D#GK;zc(9+q1a&+HasYCKg2NaTkphgR=yJ&*aZs4@GB7ZJLIE7v(-|2UY8V-^ z7#M1qzzjx)T4sh4CQxKIGcuGgGh}lx6isHVVPME&VW?#RiD$7g)UtvT1T%w3EgLwE zurNr}vV&4OD4nn~h=|m3Fx0SvkVp+HNL*N=mXo1|1I$ceVyIzb5UJs05Rs_mVyNK) z<%4V%hN8V772F^`3xlvk3L{vVbPWdsOiUammd?ab%gvCd4%5uUP;?Kh8Log4tbmOn zodLusVPmM_W@u&v+r-3B%)wZ~jwHgsP{hNS!oUz*!ig$s$_UB<%nWeVBI30?40$48 zPct*Xm4k(A*cr087@8RvYFHVvSs98-8B4esYIwkig+U^V2Q0_H(9Fybj75gK1|pRQ zE;WKRK#}B^35vE%P{e{ugLF^~GB7-_*8oLhDIX{`mn0UIWag#E7vyK=m6URV3Z2X% zNDeOrX)LKMNCjud;DU_QA_y}%HLnE9EJ{qtEG;etW#*jJJTRS`SOM1Qm!Fpk5y;E~ z3xM)AM#=&wa*#}7PG(hV3dCg~$Ahwe30QwoVkNi;%LkK?!U5_8P+3+47ET0Pk&>B~ z2IeM#$>dUyNhzs0C5d2*k@Ge<W5dcGaJB*y)X7_*aD-dN1qx?9P}qY@4Iwbe#mL3T z$0)=o#>m5H$jHMe%EZQ~!pOoX#3;@r!YITj#RQHFxFOIIMSy{UA-^ECC=pa*#+Rig wm*f|LJz1QbnwJXpByyfcH3RHH1VJ6If{HC0NU3HAijHDX`N+k{#U#uI0HFSUp8x;= literal 0 HcmV?d00001 diff --git a/__pycache__/light.cpython-33.pyc b/__pycache__/light.cpython-33.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25de9666d344f0b6096dd800e61ad58c1f75cdfd GIT binary patch literal 1651 zcmbQo!^>6h?OoVkCI*IN1|-1Dz`)?Zz`#(f&%nUop2EP8!pP79CYzZUq8J!bm>5!+ zK_XF%3@I!ODXd^N6GI9cL$C%r0|P@cBh)ky&BVaK-~=*Ffq{XchJnE~m4N}Ik%1wK z31o5#6IeSl$jo3376t}}Qcea2hTwwylAO%+jFM!Kb3o>SXpmvfAj8B!hB1Q7i)Ub{ zVFEK48B!P+f;B*v`e}evmU1vKFcjn$XO?8<=asU8T$Z1cU!(ytsT5>WacWK)E=3?K zH9$nEB?AM4vsFxJacWU<j8ke}R$^{uUW`kAa%paAUI~(rduB;YN@`hrPJVg}*zI}+ zm0;uJ<1_OzOXA}}jw%LO%)rRWSSp0<O+A<zKS&sWoE{&amzbLxA79GFz`zh6pPQdj znginUfVqXGi8)Yth+>ExVE;pP<m4wO<`l=rgZ%*}DD(^`vXempT@3P)03%wIfr1(o zbi51<3?T1<qwF3i%9t6l7#Ok`8ERP>Y9MSThFUflo0*}O9Tb&WEDSY_3=&za49yG- zwH%-bhO#+9Nv4K_p@x$|L<B_Ca4<;Jaxv7P=->v)*Kjb1q%bjLGcpu4g3@daBZEkA z4I2YoH!DL87efs<gGdcKgRqErEe}Ht4@hA)14Gdk5TlldAx{)6$jp$<!ccS)ltw{< z3?RW828JxS%h?!&MIfoyFB23bnIP|Hf<g$KBfzO3H?btOC^In!%qcENO)kwzEGh+M zn3T-4w9?{Ka3~gMWaee&r4|>1mBCXlC<)}{7v(1AWLBl7ASGr{7=yXs6o;ybje&sy zqNx<b%umWnO)dd5%Q92TQ;SMLPR%ZcP!K~Ca|$vNOF<6z0h4}UG6+nDfyqp8LIM*M zrX~SU_RPr7OOMaY$tlgv%u6gu1-Y|W4itKfJRry<%*ewi#wfrfz{tTU$H>FT3BpXJ z*z_iYyaUn-qCps(?nFT8juD#fY9I_I1`$|60WJ(c83-OdpcqNaP0CEnD**>=GPuwH znTHv=kRSyI2AH5QL_kFX)M}(Kkph)?Ap030g$AYyKS-H|l0C5o5xCI7)DLz$f}qeB UpwP5|lvZ}2lmssFgjsn+0L43W^#A|> literal 0 HcmV?d00001 diff --git a/__pycache__/operation_vector.cpython-33.pyc b/__pycache__/operation_vector.cpython-33.pyc new file mode 100644 index 0000000000000000000000000000000000000000..200dee8539d5beca61dbe0c0a5cc3b84ef2dcba1 GIT binary patch literal 7404 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 literal 0 HcmV?d00001 diff --git a/__pycache__/raytracer.cpython-33.pyc b/__pycache__/raytracer.cpython-33.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d438c668c55e9e716dd620b8256fd685dab4b5db GIT binary patch literal 2603 zcmbQo!^`#R>$@;nHU@@d1|-1Dz`)?Zz`#&k&A`Br!oZNi$dJRpkjuyr#mJD$#1O^A zzz7m$V#r};$Yo)OVuA3P8FE+|a@iQ7*dTlsh8%W=Tn>gP4u)J#hA2)3M)wp}h7>l2 z76uU6%)}7I#gM|zkir2HiQ;BR;bchR0<(D-Qn(p{HFy{p7&1W)(_ms?U?>$}U|=Z7 z$j?iU&&<gw&CSe9EJ-aDVqjoM%uUKn%qu|>)?fr_-~{Q<D@iRXPE9U>2(d9RFodNh zm*f{g%wz>=FDgo`ECsQuQj7A7lR<hxwt{Go#ZI8GP+(wSs9|7mO=SQDLka^Z7*ZG+ zQkcLFW@boXW(d|`0oe))zM#a)WDpH921J95aRwP91~P^bWKui>Lk$y{!3YZEV6glA zAg<yADJ@AXD#^@Ck1xp2%quD71jR*WQEGBYW`3Rq$jnlZZN;fMX{7{}gPfrOB1&x; z7#N(bVnT~ki;82MQuDGBb2IZ|T=J7kb5rw5kc8YbOJY(|%i?qL(_@MfD@%$JlT(ZI z3MxxE7#JAh<1_OzOXB0%LGA=OgMpEgu@n?tL5Y=mFj+rHctAAdCFZ8a$Cq+}b?4@% zl;(iAAT9Cng{6r(P<e=Ai0R-Ef$GS~PfpA!j*kcX0!&cBE1*yeN~{E>iDFO;2{4vI zh2W9L&%nUI4GJ@mPjeX=7}6OSYMB{I7(ltAnUSHEg`pyop@xwmi;=-4Hjbf|m7#=* zp@tO{vCT{jwQLMEY@q1PW@ado0kN}KKvG$(3=&yv49yG-wd@Qf><l$53^nWwAPp=~ zb~Y13Q58r-EeAtk6+@v62!+?MAgl(dSj<qu0ZM}@Odv9ynW34HA-IH-p@xG2WDy5L z78lr5PKF9suq(M4Tw<*lYPlF{I2lTK7;3nXl=6bvTv&{3W@Rw1<zy&4#1IZLnTsKd zk0Fbnp_UtDOqKx1A2G}fwLA>9ybQH`AOlJS!QSEl<%?#p<C>WmN(4c!1bLSiDvlz^ zhY*DN1e}2Uz>$)fmj*5hGC{dg1C;B*IW{dPKe40~6hrw*S*gh-@j02rkj#<^%lP1Y z;+LP73QoEO`Nf%_EQBr7fKqZ^eo-#i!raWfQc%i(lomM38L$e7&ESNZlbN0YbpzJY z3S=P2hQu7OV{#KqQj0PZbHH9n&d<p&g0k|9QXq~<tk3`@K`;kaN);!k=B0vdPEO2C zElLD?1@2u)2!QfYN@j6MVqS7;DJaPD!4?*!7MJFfB$j}MQc6KaC+8#<7stc3LmdEf z3fM#7oDFtfJk+nCY?2&b0d`h$d?l2w0%uGxL51AO$-uw>E_ULJ5-UM5T&x5t!Wh{Y zc^Cy4`5Ac_#lWNhqY$GoqbQ>QqXi>BqbMV|sDx`w24!rJK9F&sPyrXib3nx~149-A zLoE|HKQe-IH50f<W(MW$G;m%5W$!$O5@wKiGbo2AfO2?6I9Ld*!X?%doXZ)&8IBc{ zV?o)NouPykl%;DJLB=;TGt_c`a~C+zgK|4qC8!!@U}$AxNMmNODRgHDFEn8Q<?&!} zHQ<*C3T6#ZAq!67nYoGSsquM5`Q^pP{N((cVsNa1YcDXXC^0V`l0u3SE8`O(83G<8 zU?s`<`9&!joS+H|lqjJo2~-I}k{2kb^5Szc)ALe`!AUzW9+U#|KwOZE64TN$lQSS` zD-)cYvcRbTmPkR0i@-?%Oi&>`fHD-kCW<dg%}Yrwk^>dXpuzxD0dX>lG72*aGYT;Z zF{(3yn+xdb{WN$%J_dOclCnXD64|Bz=K^>>$;{6KCp5SK*uMON)S^UC@e*GKZe)OS zDYOIuS(;axTL5WlB%(Gtz+o4ZSP3>05mO-Nq5A<Go(O^pAq$FY8%UjO2P!Lyc^DWN Q#25t_1sKJcgjson0gmfdSO5S3 literal 0 HcmV?d00001 diff --git a/__pycache__/scene.cpython-33.pyc b/__pycache__/scene.cpython-33.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac3f713769654225108a1111d89b0afaa5f39b8a GIT binary patch literal 2054 zcmbQo!^_2S_gxqVGXq010}^0nU|?`yU|=YAXJBARVPHsMWXNG)2ystgVn|_TXkh@6 z%}fkYj12B6EDR~EU?ElpkPs7tdkPyv3OiVc9W2Dmkix+btij2^z>o>DM1zrmfuR&c zXeEP4kQj(&Vqjo!0@<p-z`#($z~Gw70J0*5fgy?s<b)I^kfBk`AlrjASU`rbF)%O$ z7i6Rsr6z;;Ad^5e$RuZwN%A0*7(s@`GceRJff<YpHOycJ6Ub}9VAuF*fV^A^GA=na zucRmy%q&Vw$t*1{<zQf7$W1IsEy_&HfmjQ&qc}Aut(294fgw3RzbFOFDoU)(&qGxX za*+mzDCK5gV9?WxDNat!OVul=1S^Y=&&<m#iH`@H2eO=jk&}^=v6LU~Ej^eLKZwmB zx5UTiCFZ8a$Cq+3Ffhc&=jNxB=76|7U~XY)Vh&Uuq8MTY*qcxtIr+(nImPkuV26PT z4A+4i0|{7Az!ZZ5RDcm2C=gLfBM#&=Uuc*nvx5SNfq?-;gKPpvofZD5t6>4hAu~e_ zE11E;P{Rghup-AQ$Q$6ONzTv7FDeCDkeHj4nV44sW~XGPrIi+^g5#pNAT_x(C$XrM z6O?c=GV?O?Qj3ehAy$-{mXn%Xl9`{U0WzT!99@X$r;f>>Fu)!cps<1^15lI~^MKTX zQwk`xa59z(GB7Z}LUW)}49Jx*H-Li>6q5ps;IM^>V^1{}pqR#=-BVb=Ssz^1q_Bb6 zte`?BSOa7&IEI5k84JS#a8eRuU|>iG7b)>@1|xDZ0XY?%1@e=!Qj<&Kb25udz%ieb znVtdRLh=tR=D`sKCcxTo<!fP3QUd7#<?B*DP_72K5*|g#Ad5kf38Fz5>|7B@cw{j! zWHB<-FfueVGBBnvFu+PGkUFrf$c_ai^u&UK)Vvf8usq08a0vw}So6Uy1ruP6$j${N zsKk_%c!*)*AP0jCU|=j2fIAl<Pride_8>wNT$12)Zw}b0U;@Lvpri$I57;azB<F(5 zOmOJJrTsKO!2(W!WR;oVBmgoE5;)+J0mKE{4M`9nZ^g$GQJ{iq3UCq?0=XIFE&)a! z79M6q+J%<zpkU80NG(bPl{fKasmUezMd09q6ue;H!15D9GdQpi1V*rdvWX3(rmzDg OiDHloxR`|5ggF87^NNB1 literal 0 HcmV?d00001 diff --git a/camera.py b/camera.py index a4e5e23..083f32b 100644 --- a/camera.py +++ b/camera.py @@ -1,4 +1,5 @@ from operation_vector import Vector +from raytracer import Ray class Camera: def __init__(self, image_nrows, image_ncols, distance_focale): @@ -11,6 +12,6 @@ class Camera: x = (n-row)/n n = self.image_ncols//2 y = (n-col)/n - return Vector((x, y, self.focal_length)) + return Ray(Vector([0,0,0]), Vector((x, y, self.focal_length))) diff --git a/light.py b/light.py index c324f9d..674fb4e 100644 --- a/light.py +++ b/light.py @@ -13,7 +13,13 @@ def phong_illuminate(light, position, normal, object, viewer): R = 2*(L*N)*N - L V = (viewer - position).normalized() - i = ((kd*(L*N) + ks*(R*V)**alpha))*(N*L > 0) + if (N*L) <= 0: + return 0*position + i = ((kd*(L*N) + ks*(R*V)**alpha)) + if i < 0: + i = 0 + elif i > 1: + i = 1 return i*(light.color ** object.material.color) diff --git a/one_sphere.png b/one_sphere.png deleted file mode 100644 index 090a8d4f232416bfe3d6ea894b2eb203cac83bfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6168 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 diff --git a/operation_vector.py b/operation_vector.py index 0c9825c..fe5ffd2 100644 --- a/operation_vector.py +++ b/operation_vector.py @@ -3,12 +3,12 @@ from random import random class Vector: def __init__(self, coord): x, y, z = coord - self.x = x - self.y = y - self.z = z + self.x = float(x) + self.y = float(y) + self.z = float(z) def coord(self): - return (self.x, self.y, self.z) + return (float(self.x), float(self.y), float(self.z)) def __add__(first, second): if type(second) == Vector: @@ -19,7 +19,7 @@ class Vector: def __rmul__(vector, item): d, e, f = vector.coord() - return Vector((item*d, item*e, item*f)) + return Vector((float(item*d), float(item*e), float(item*f))) def __radd__(vector, item): return vector + item diff --git a/raytracer.py b/raytracer.py index 4b746b3..fe34768 100644 --- a/raytracer.py +++ b/raytracer.py @@ -25,7 +25,7 @@ def trace_ray(ray, scene, camera): color += phong_illuminate(light, class_intersect.position, class_intersect.normal, class_intersect.object, Vector([0,0,0])) color_object = class_intersect.object.material.color c_x, c_y, c_z = color.coord() - return Vector([min(c_x,1), min(c_y,1), min(c_z,1)]) + return Vector([max(min(c_x, 1), 0), max(0, min(c_y, 1)), max(0, min(c_z,1))]) def raytracer_render(camera, scene): n_lignes = camera.image_nrows @@ -33,8 +33,7 @@ def raytracer_render(camera, scene): affiche = zeros((n_lignes, n_colonnes,3)) for i in range(n_lignes): for j in range(n_colonnes): - ray_direction = camera.ray_at(i, j) - ray = Ray(Vector((0,0,0)), ray_direction) + ray = camera.ray_at(i, j) color = trace_ray(ray, scene, camera) affiche[i,j,:] = color.coord() return affiche diff --git a/scene.py b/scene.py index ff44e7b..c18a96b 100644 --- a/scene.py +++ b/scene.py @@ -7,12 +7,13 @@ class Sphere: self.material = material class Material: - def __init__(self, color, ambiant, diffuse, specular, shininess): + def __init__(self, color, ambiant, diffuse, specular, shininess, reflection): self.color = color self.ambiant = ambiant self.diffuse = diffuse self.specular = specular self.shininess = shininess + self.reflection = reflection class Scene: def __init__(self): diff --git a/script_one_sphere.py b/script_one_sphere.py index ff511e4..eeec468 100644 --- a/script_one_sphere.py +++ b/script_one_sphere.py @@ -3,13 +3,22 @@ from light import Spotlight from camera import Camera from raytracer import raytracer_render from matplotlib.image import imsave +from math import cos, sin, pi camera = Camera(200,200,2) -materiau_sphere = Material(Vector((0,0,1)), .1, .3, .8, 20) +materiau_sphere = Material(Vector((0,0,1)), .5, .3, .7, 20, 1) sphere = Sphere(Vector([0,0,3]), 1, materiau_sphere) -lumiere = Spotlight(Vector((1, 1, 0)), Vector((1,1,1))) -scene = Scene() -scene.add_object(sphere) -scene.add_light(lumiere) -affiche = raytracer_render(camera, scene) -imsave('one_sphere.png',affiche) +for theta in range(36): + a = 3*cos(theta*pi/18) + b = 3*sin(theta*pi/18) + lumiere = Spotlight(Vector((0, a, 3+b)), Vector((1,1,1))) + lumiere_2 = Spotlight(Vector((0, -a, 3-b)), Vector((1,1,1))) + scene = Scene() + scene.add_object(sphere) + scene.add_light(lumiere) + scene.add_light(lumiere_2) + affiche = raytracer_render(camera, scene) + imsave('one_sphere_' + str(theta) + '.png',affiche) + print(theta) + + diff --git a/tests/01_camera_ok.py b/tests/01_camera_ok.py new file mode 100644 index 0000000..362b228 --- /dev/null +++ b/tests/01_camera_ok.py @@ -0,0 +1,14 @@ +# Show to python where to find the Camera module +import sys +sys.path.append('..') + +# Import the Camera module +from camera import * + +# Instantiate a Camera object +c = Camera(100, 200, 3) + +# Test its members +assert(c.image_nrows == 100) +assert(c.image_ncols == 200) +assert(c.focal_length == 3) diff --git a/tests/02_rayon_ok.py b/tests/02_rayon_ok.py new file mode 100644 index 0000000..1ce0c2f --- /dev/null +++ b/tests/02_rayon_ok.py @@ -0,0 +1,31 @@ +# Show to python where to find the Camera module +import sys +sys.path.append('..') + +import numpy as np +from camera import * +from operation_vector import Vector + +c = Camera(100, 200, 3) + +r_center = c.ray_at(c.image_nrows / 2, c.image_ncols / 2); + +assert (abs(r_center.direction*Vector([0,0,1]) - r_center.direction.norm()) < 0.01, "c.ray_at(c.image_nrows / 2, c.image_ncols / 2) should have the direction [0,0,1].") + +r_zero = c.ray_at(0,0); + +r_zero_ref_dir = Vector([1,1,c.focal_length]) +r_zero_ref_dir = r_zero_ref_dir / r_zero_ref_dir.norm() + +assert abs(r_zero.direction* (r_zero_ref_dir) - + r_zero.direction.norm()) < 0.01, "c.ray_at(0,0) should have the direction [1,1,camera.focal_length]."; + + +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."; + + diff --git a/tests/03_sphere_intersection_ok.py b/tests/03_sphere_intersection_ok.py new file mode 100644 index 0000000..d7893c8 --- /dev/null +++ b/tests/03_sphere_intersection_ok.py @@ -0,0 +1,33 @@ +# Show to python where to find the modules +import sys +sys.path.append('..') +from operation_vector import Vector + +from scene import * +from camera import * +from intersection import * + +def is_parallel(v1, v2): + return ((v1*v2) / (v1.norm() * v2.norm()) - 1.) < 0.01 + +s = Sphere(Vector([0,0,3]), 1, Material(Vector([0,0,1.]), 1, 1, 1, 1, 1)) + +r = Ray(Vector([0,0,0]), Vector([0,0,1])) +i = intersect(s, r) +assert (i.position == Vector([0,0,2.])), "Error with a ray starting outside the sphere." +assert is_parallel(i.normal, Vector([0,0,-1.])), "Error with the normal of a ray starting outside the sphere." + +r = Ray(Vector([0,0,10]), Vector([0,0,-1])) +i = intersect(s, r) +assert (i.position == Vector([0,0,4.])), "Error with a ray starting outside the sphere." +assert is_parallel(i.normal, Vector([0,0,1.])), "Error with the normal of a ray starting outside the sphere." + +r = Ray(Vector([0,0,3]), Vector([0,0,-1])) +i = intersect(s, r) +assert (i.position == Vector([0,0,2.])), "Error with a ray starting inside the sphere." +assert is_parallel(i.normal, Vector([0,0,1.])), "Error with the normal of a ray starting inside the sphere." + +r = Ray(Vector([0,0,5]), Vector([0,0,1])) +i = intersect(s, r) +assert i is None, "Error with a ray not intersecting the sphere: intersect should return None." + diff --git a/tests/04_material_ok.py b/tests/04_material_ok.py new file mode 100644 index 0000000..1f12e23 --- /dev/null +++ b/tests/04_material_ok.py @@ -0,0 +1,14 @@ +import sys +sys.path.append('..') +from operation_vector import Vector + +from scene import * + +m = Material(Vector([0,0,1]), 0.1, 0.2, 0.3, 0.4, 0.5); + +assert((m.color == Vector([0,0,1]))) +assert(m.ambiant == 0.1) +assert(m.diffuse == 0.2) +assert(m.specular == 0.3) +assert(m.shininess == 0.4) +assert(m.reflection == 0.5) diff --git a/tests/05_phong_ok.py b/tests/05_phong_ok.py new file mode 100644 index 0000000..9d7dedf --- /dev/null +++ b/tests/05_phong_ok.py @@ -0,0 +1,32 @@ +# Show to python where to find the Camera module +import sys +sys.path.append('..') +from operation_vector import Vector + +# Import the Camera module +from scene import * +from light import * + +s = Sphere(Vector([0,0,3]), 1, Material(Vector([0.1,0.2,0.3]), 0.1, 0.2, 0.3, 0.4, 0.5)); +n = Vector([0,0,-1]) +l = Spotlight(Vector([0,0,0]), Vector([0,0,1])); +p = Vector([0,0,2]) +v = Vector([0,0,0]) + +assert((phong_illuminate(l, p, n, s, v) == Vector([0,0,0.15]))) + +s = Sphere(Vector([0,0,3]), 1, Material(Vector([0.1,0.2,0.3]), 0.1, 0.2, 0.3, 0.4, 0.5)); +n = Vector([0,0,-1]) +l = Spotlight(Vector([1,1,0]), Vector([0,0,1])); +p = Vector([0,0,2]) +v = Vector([0,0,0]) +assert((phong_illuminate(l, p, n, s, v) - Vector([0, 0, 0.13])).norm() < 0.01) + + +s = Sphere(Vector([0,0,3]), 1, Material(Vector([0.1,0.2,0.3]), 0.1, 0.2, 0.3, 0.4, 0.5)); +n = Vector([0,0,-1]) +l = Spotlight(Vector([0,0,10]), Vector([0,0,1])); +p = Vector([0,0,2]) +v = Vector([0,0,0]) +assert((phong_illuminate(l, p, n, s, v) == Vector([0,0,0]))) + -- GitLab