366 lines
62 KiB
Plaintext
366 lines
62 KiB
Plaintext
|
<TeXmacs|1.99.11>
|
|||
|
|
|||
|
<style|<tuple|base|french>>
|
|||
|
|
|||
|
<\body>
|
|||
|
<\hide-preamble>
|
|||
|
\;
|
|||
|
|
|||
|
<assign|by-text|<macro|>>
|
|||
|
|
|||
|
<assign|verbatim|<macro|body|<with|color|darker
|
|||
|
grey|<with|font-family|tt|language|verbatim|<arg|body>>>>>
|
|||
|
</hide-preamble>
|
|||
|
|
|||
|
<doc-data|<doc-title|Projet <verbatim|C++> : Moteur d'optique g<>om<6F>trique
|
|||
|
<name|2d>>|<doc-author|<author-data|<author-name|F<>lix Faisant>>>>
|
|||
|
|
|||
|
<em|Le code n<>cessite la biblioth<74>que SFML pour l'affichage (paquet
|
|||
|
<verbatim|libsfml-dev> sur Mint ou Debian).>
|
|||
|
|
|||
|
<subsection|Objectifs et m<>thodes>
|
|||
|
|
|||
|
Le but de ce projet est de simuler les lois de l'optique g<>om<6F>trique sur
|
|||
|
une sc<73>ne <name|2d>, et ainsi de construire un moteur d'illumination de
|
|||
|
sc<73>nes <name|2d>. Le principe est simple :
|
|||
|
|
|||
|
<\itemize-arrow>
|
|||
|
<item>Les <strong|sources> envoient des rayons lumineux, par exemple dans
|
|||
|
toutes les directions pour une source isotrope, ou dans une seule
|
|||
|
direction et de fa<66>on <20>tendue pour une source de type "soleil".
|
|||
|
|
|||
|
<item>Les rayons sont intercept<70>s par les <strong|objets> de la sc<73>ne.
|
|||
|
Suivant l'objet, le rayon peut <20>tre r<>fl<66>chi, r<>fract<63>, diffus<75>, filtr<74>,
|
|||
|
absorb<72><text-dots> L'objet r<>-<2D>met alors z<>ro, un ou plusieurs rayons.
|
|||
|
|
|||
|
<item>Des <strong|<7C>crans> accumulent l'intensit<69> des rayons qu'ils
|
|||
|
interceptent sur une matrice de pixels.
|
|||
|
|
|||
|
<item>Le processus d'interception - r<>-<2D>mission est r<>p<EFBFBD>t<EFBFBD> jusqu'<27> ce que
|
|||
|
le rayon soit totalement absorb<72>.
|
|||
|
</itemize-arrow>
|
|||
|
|
|||
|
On peut alors se servir des pixels des <20>crans comme image, comme un
|
|||
|
<name|ccd> de cam<61>ra (<name|1d> !) si on a plac<61> une lentille devant, ou
|
|||
|
comme la luminosit<69> qu'aurait un mur <20> cet endroit (par exemple pour
|
|||
|
illuminer une sc<73>ne d'un jeu de plateforme). Plut<75>t qu'un long discours,
|
|||
|
mieux vaut regarder les exemples page 2.
|
|||
|
|
|||
|
On peut voir <20>a comme une m<>thode de Monte-Carlo. C'est tr<74>s inefficace
|
|||
|
pour construire des images (on appelle <20>a alors le <em|pathtracing>) car
|
|||
|
une toute petite fraction des rayons <20>mis arrivent au "<name|ccd>" (comme
|
|||
|
pour une cam<61>ra r<>elle)<\footnote>
|
|||
|
Pour faire du rendu d'image r<>aliste performant, les rayons sont lanc<6E>s
|
|||
|
depuis l'<27>cran et sont propag<61>s dans le sens inverse (on appelle <20>a alors
|
|||
|
le <em|raytracing>). C'est beaucoup moins simple <20> impl<70>menter pour les
|
|||
|
processus irr<72>versibles (diffusion<text-dots>).
|
|||
|
</footnote>. C'est par contre adapt<70> pour faire une illumination
|
|||
|
physiquement r<>aliste (on appelle <20>a alors l'illumination par
|
|||
|
<em|radiosit<69>>).
|
|||
|
|
|||
|
<\compact>
|
|||
|
Les diff<66>rents objets impl<70>ment<6E>s ici sont :
|
|||
|
|
|||
|
<\itemize-dot>
|
|||
|
<item>Des lignes ou des arcs de cercles, dont les calculs
|
|||
|
d'interception sont d<>taill<6C>s dans <verbatim|lois.pdf>.
|
|||
|
|
|||
|
<item>Des dioptres (lois de Snell-Descartes et coefficients de Fresnel,
|
|||
|
d<>taill<6C>es dans <verbatim|lois.pdf>), des miroirs, des objets
|
|||
|
diffusants (<hlink|diffusion lambertienne|https://fr.wikipedia.org/wiki/Loi_de_Lambert>
|
|||
|
ou plus sophistiqu<71>), des <20>crans, des filtres<text-dots>
|
|||
|
|
|||
|
<item>Ou bien des objets non localis<69>s, comme du brouillard.
|
|||
|
</itemize-dot>
|
|||
|
</compact>
|
|||
|
|
|||
|
Pour impl<70>menter les couleurs, on choisit de rester proche des lois
|
|||
|
physiques en attribuant un <strong|spectre> discret <20> chaque rayon (ici 4
|
|||
|
longueurs d'onde). De plus, il faut prendre en compte la polarisation
|
|||
|
<math|><name|te> / <name|tm>, qui se comportent diff<66>remment pour la
|
|||
|
r<>flexion/r<>fraction<\footnote>
|
|||
|
Le plan d'incidence des rayons est toujours le m<>me : le plan o<> vivent
|
|||
|
les objets <name|2d>. Ainsi, les polarisations <math|><name|te> et
|
|||
|
<name|tm> (relatives au plan d'incidence) sont toujours les m<>mes, on
|
|||
|
peut donc s<>parer la lumi<6D>re de fa<66>on globale en composantes <name|te> et
|
|||
|
<name|tm>, et les traiter s<>par<61>ment.
|
|||
|
</footnote>. Ainsi, chaque rayon poss<73>de <em|8 composantes>. De plus, on
|
|||
|
oublie tout ph<70>nom<6F>ne de nature ondulatoire. On travaille alors directement
|
|||
|
en <em|intensit<69> lumineuse>, plut<75>t qu'en amplitude, et on les additionne
|
|||
|
simplement. Cela simplifie largement l'impl<70>mentation.
|
|||
|
|
|||
|
<subsection|Structure du code>
|
|||
|
|
|||
|
Les fichiers <verbatim|Util.h>/<verbatim|Util.cpp> impl<70>mentent des
|
|||
|
structures et fonctions utilitaires classiques : un vecteur <name|2d>
|
|||
|
<verbatim|vec_t> et un point <name|2d> <verbatim|point_t> avec les
|
|||
|
surcharges d'op<6F>rateurs usuelles, les rotations/translations/homoth<74>ties,
|
|||
|
une structure <verbatim|angle_interv_t> qui impl<70>mente un intervalle
|
|||
|
angulaire dans <math|\<bbb-R\>> modulo <math|2\<pi\>><text-dots> Le fichier
|
|||
|
<verbatim|sfml_c01.hpp> contient des fonctions utilitaires pour l'affichage
|
|||
|
avec SFML, notamment pour convertir les coordonn<6E>es
|
|||
|
<math|<around*|[|0,1|]>\<times\><around*|[|0,1|]>> en coordonn<6E>es
|
|||
|
fen<65>tre.<new-page>
|
|||
|
|
|||
|
<new-page>
|
|||
|
|
|||
|
La structure <verbatim|Rayon> est impl<70>ment<6E>e dans
|
|||
|
<verbatim|Rayon.h>/<verbatim|Rayon.cpp>. Un rayon est d<>fini par son point
|
|||
|
d'origine, sa direction (angle par rapport <20> l'horizontale), et son spectre
|
|||
|
de couleur/polarisation en intensit<69>. La structure <verbatim|Specte>
|
|||
|
contient les 8 composantes ainsi que des routines de manipulation des
|
|||
|
composantes.
|
|||
|
|
|||
|
<subsubsection|Objets>
|
|||
|
|
|||
|
Pour d<>crire le contenu de la sc<73>ne, on utilise un arbre de classes (voir
|
|||
|
diagramme page 4), pens<6E> pour <20>tre facilement extensible, <20>viter toute
|
|||
|
duplication de code, et utiliser le polymorphisme au maximum.
|
|||
|
|
|||
|
On distingue les sources, qui ne font qu'<27>mettre des rayons, de tous les
|
|||
|
autres objets de la sc<73>ne. Tous les types de sources d<>rivent de la classe
|
|||
|
virtuelle <verbatim|Source>, et impl<70>mentent la m<>thode
|
|||
|
<verbatim|genere_rayons> qui renvoie un
|
|||
|
<verbatim|vector\<less\>Rayon\<gtr\>>. On pourra regarder la classe
|
|||
|
<verbatim|Source_SecteurDisqueLambertien> (<verbatim|Source.h:127>), qui
|
|||
|
impl<70>mente une source <20>tendue lambertienne en forme de secteur.
|
|||
|
|
|||
|
Tous les autres objets de la sc<73>ne d<>rivent de la classe virtuelle de base
|
|||
|
<verbatim|Objet>, qui d<>clare l'interface commune utilis<69>e lors de la
|
|||
|
propagation (interception puis r<>-<2D>mission) des rayons, et pour
|
|||
|
l'affichage. Un objet est capable de <strong|tester l'interception d'un
|
|||
|
rayon> avec la m<>thode <verbatim|essai_intercept(rayon)>, et, le cas
|
|||
|
<20>ch<63>ant, de <strong|r<>-<2D>mettre le rayon> avec <verbatim|re_emit(rayon,
|
|||
|
intercept)> (o<> <verbatim|intercept> est une structure opaque renvoy<6F>e par
|
|||
|
<verbatim|essai_intercept>, conservant les informations de l'interception)
|
|||
|
:
|
|||
|
|
|||
|
<\big-figure|<image|<tuple|<#255044462D312E350A25B5EDAEFB0A332030206F626A0A3C3C202F4C656E6774682034203020520A2020202F46696C746572202F466C6174654465636F64650A3E3E0A73747265616D0A789C957D4B8F6DBD6DE57CFF8A330EE0EAADB734CD2440033D703234326854FAFA43507790F4C07FBFB9D6A21EFB54C10DE3837D8B3C7A5014459194C4FD5FD7FD31E2C821BEBEFFF1DF7F7DFD8FFF7DBFFEFA7FAFFB85FFFEF55FECB7565E7F33F87FDAFFFEF3FACBBF1BE67EFDC7955FFFEBF55FAFC0627FC23FA1DC1FB9C6DADAEBF3F715EEF411637B85FBFE48A5BC7EBF420C1FF58EAF363E5A0FAF10AC9D915FA97CC496ACB6FD1ADA2BDF1FB1BC3E5F61E48F16CAF54AF9A396F88A217CC45A5F7D7CE462CD8EF651AC7688F1A3E4860AADA3C22B54A3181D5BC51EAD446A1FE11E9751622DF66188FBA366F4D1B3B5D1AD0DFBA1F4578F1F3D5B85BB7F5847EF03F87CFDF1C3A0FEF99F5E7FBEFE0E1BE21D3F9231367D8481F2312634DE3FC6B031191501449557ACF163F46CA88FD4319CD86D52EA78A564F87EBDE228C6BDF2CAED231B13AD4D5252CAC71D513EC54EEAAD9D9ABB71CDCAE5F0AAF9231B25A9D68F3B19583FD26D4CFD7CFD9BD10D4685629D1C531D82CDCDDFAEBF18C5F79D9B3170FE61136FD3FEF7C66A5214C5E69838E1C6DFBBBF5AF9081543AB2439978FD2ACD9DA3E7AB589AF9B1A08DA12B07FA4A760F372A7576B1F23BCBED8DCDF93CD47719B946232054A2838AA1EC08D7EA711F71FC6A27FA0D5D23903C504B61F8DE681C6F61FFF58A326DC10772B03D9FEFA711AFF4E73257F84945EBD7DB496BCB9545EE3E6D2F98238159B1093355307B37936669A21DEC1842DD952FC08C62763FB303936197604D664B7691946E25850FB883D71410BCE1FA39804B2AEF13C7D6463029B365171D0C4DF56DADDF6CF46B7FD6AC26E2A6242D6F218170B0B314C830455ED7552F5463596F142DD1FC1D6BD0980AD52282147001C21A3C198EA06D921FB23E20241C97E98D56D6CF9EE7B300231F421952404C0606BD86B3B789DACF202EA9FD573DCD43DA8FF7140BFAE68EA35A78C3E311B364647980242A35F567850951C88FA51C0B160CBA110D13EEE9C2EB45BB93250C7D6318A0C2F228477A3467A6F3F2092295B9B78C398EE2269C49C8859E78FEFE4DB886C99D6681B470AA6E9A6322D392D4CB4CD2043104CC39BC46FD874E36D23FD9C18E3351A332DC4263035A6ABC8DC28353B615469A6B1FB51C2F699D6D8424BF53A109DE2F9B9314687AD36B6D0F341E673209CC185B395DD1A07677C6B1B83568AED24210EF27EC3BB5B62303868FBB49BB0C6B914D6E08AAF8588FD069BE42A61DB93C9B8B7701D88CDC28999745813F920F339909F0767B3691B5BA991DB7408D4C22972879F9868EC49B62598C2320BC0188F7D3B028EB69A408915C8099369985B9284BF7223A66365DABFEA25697CE8754168C2E4ABF589B1F1C21C511F58030B0429AA20840D5EED676D1D9871582918A14DCA058642043F170AF283E50E22AB887A60DA9D380D366F1A87A9744770D158C709D689F514236BE4AA59A8F980C1139BD0CF0313354F686084EBE0EF73063853DF66E5D7FFC75C8449547B87A131284826D2AF3F9966B181FDF7FF41F5B97D8C2413C40C2223F8F76B048ED961DB8260FF546374AC13B2BDB3173071C2DDA6C1D8E1550B6CA13C1B76C80A67726AFE6A9B86CD3076E3B8006BD7F4F5F53911E8D610A8691237497A100CF64C8C751F20C606D3E6126CB54D342AF699E48077F43941B32C6D57BBBC5EC1CA4D8B7E41563672CB9FBF5AE3A3CDAA13126330002166AF56358C45D083DC9F06F0EBB2BDE5B66DD99A0F378724B826E3302C8001BED50336D9C5EF30BB8BE0411E19AD97CA27B3200C81812FD8DB67F97E87EF70833D64304DEB66DBFA3B6657F9E31BD1BF6899C31006AAD3DB98083375CCFE02088BDD850260BFC79619D892B1B56B17C85495ABBA836AFEF344D4D467758003468E9ABF26FCB9FBDF059C5C557F503F5D8DC78030464844C5E4570E3BC02782A408F12584CDBF21305B07D84D821DBC60F549D266818A1D5F2E59EE794A7CC0DEDE8F054002F68A3082CC6249947F734F5E135CAB76214C067A7F2DFA278B0714928317CB0F2D732F60E440391B88E18158AF3E4A20F5B621348A01A8FF22C2FA23DB436373BD91E7771CBB3F811A8ED7D7EF9D7B8781C5B8E3D45E93BB9A14E388569BD60F9D5888BB106460253FE37DF0F35E52E36D3AE64B1829A048923BDDDAD9DEB3BF1F4930B9805DB9F485BCA1DE1702A0395B006D5B2108EB14C3141B4C6717B3972F94E79A0606FE29186F54A246697B56D4DB5A3966C6E6BC579679513019B170201304D159D794099CF2596C9994298F68197457586F124F737E13B9055201D6C4DF6BDB50A012F83C11D97FEF839C6D1CB62DD86AB2E1B00887D5BE0A9891C2E2506C201416B58BB62807170DD1216B17CA8FCAC510289DD85EFB5A3BE82EF763ED8889EB67D38F8972632BF33AE13B179F14226EC9051CA146BD3FD478AE742D6B9B53A05FD55861A0C5C0E85C2608A37478714724FD0CF77C49CB214C9744EE4DBE207183FEE7217263EA3F35627DD5B845AED3D33844CED6707F485C67DC63499CA9C97AC89477B764CE1C92434F9837623F6F9913BC856EC22E75F004CD809D52676D81F443EA066CE243EC0635F1143B87B6D82D44F6DFE3D85265ADDF659C620767AA6EB9346AEE9697DCC1F90AFD903B4380952E771711D849A6DC59736D2C338AFDE574CA9D58B9040F5372C8DD04A7D8099E52D7E93F4CA9835E2F5BEA3009FA954D1938
|
|||
|
Sc<53>nario typique (celui de <verbatim|Scene::interception_re_emission>)
|
|||
|
d'utilisation des objets.
|
|||
|
</big-figure>
|
|||
|
|
|||
|
Cela semble compliqu<71>, mais l'interception et la r<>-<2D>mission sont s<>par<61>s
|
|||
|
pour des raisons de performance : les calculs de r<>-<2D>mission peuvent <20>tre
|
|||
|
lourds (e.g.<nbsp>lois de Fresnel) et ne sont pas n<>cessaires <20> chaque
|
|||
|
interception (par exemple si le rayon a <20>t<EFBFBD> intercept<70> plus en amont par un
|
|||
|
autre objet). <verbatim|essai_intercept> renvoie aussi la distance entre le
|
|||
|
point d'<27>mission du rayon et l'interception, qui sert <20> d<>terminer quel est
|
|||
|
l'objet le plus proche sur la trajectoire du rayon (voir plus loin pour
|
|||
|
l'utilisation de ces m<>thodes).
|
|||
|
|
|||
|
D'un c<>t<EFBFBD>, on d<>finit alors des classes (virtuelles) qui s'occupent
|
|||
|
uniquement de la <strong|g<>om<6F>trie> et de l'interception des rayons.
|
|||
|
<verbatim|ObjetCourbe> d<>crit une courbe/interface bien d<>finie, et la
|
|||
|
structure opaque renvoy<6F>e par <verbatim|essai_intercept> contient le point
|
|||
|
d'incidence, l'angle d'incidence dans le rep<65>re de la sc<73>ne, l'angle <20> la
|
|||
|
normale de la courbe, et le c<>t<EFBFBD> sur lequel le rayon est intercept<70>.
|
|||
|
L'interception est enfin impl<70>ment<6E>e pour deux g<>om<6F>tries particuli<6C>res :
|
|||
|
<verbatim|ObjetLigne> d<>crit un segment, et <verbatim|ObjetArc> d<>crit un
|
|||
|
arc de cercle. On pourra regarder le header <verbatim|ObjetsCourbes.h> et
|
|||
|
les m<>thodes <verbatim|ObjetArc::essai_intercept_courbe>
|
|||
|
(<verbatim|ObjetsCourbes.cpp:100>) et <verbatim|ObjetCourbe::essai_intercept>
|
|||
|
(<verbatim|ObjetsCourbes.cpp:10>).
|
|||
|
|
|||
|
D'un autre c<>t<EFBFBD>, on impl<70>mente la <strong|physique> et la
|
|||
|
<strong|r<>-<2D>mission> des rayons dans des classes virtuelles ind<6E>pendantes
|
|||
|
de la g<>om<6F>trie : <verbatim|ObjetCourbe_Milieux> pour la
|
|||
|
r<>flexion/r<>fraction sur un dioptre, <verbatim|ObjetCourbe_Diffusant> pour
|
|||
|
une surface diffusante, <verbatim|ObjetCourbe_Miroir> pour les
|
|||
|
miroirs<text-dots> Ces classes impl<70>mentent, elles, la m<>thode
|
|||
|
<verbatim|re_emit()>. On pourra regarder
|
|||
|
<verbatim|ObjetCourbe_Milieux::re_emit> (<verbatim|ObjetMilieux.cpp:20>),
|
|||
|
qui impl<70>mente les fameuses lois
|
|||
|
|
|||
|
<\equation*>
|
|||
|
\<theta\><rsub|<text|r>>=\<theta\><rsub|<text|i>>,<space|1em>n<rsub|2>*sin<around*|(|\<theta\><rsub|<text|t>>|)>=n<rsub|1>*sin<around*|(|\<theta\><rsub|<text|i>>|)>,<space|1em><with|math-display|false|R<rsub|<text|TE>><separating-space|0.2em>=<separating-space|0.2em><around*|\||<frac|n<rsub|1>*cos
|
|||
|
\<theta\><rsub|<text|i>>-n<rsub|2>*cos
|
|||
|
\<theta\><rsub|<text|t>>|n<rsub|1>*cos
|
|||
|
\<theta\><rsub|<text|i>>+n<rsub|2>*cos
|
|||
|
\<theta\><rsub|<text|t>>>|\|><rsup|2>,<space|1em>R<rsub|<text|TM>><separating-space|0.2em>=<separating-space|0.2em><around*|\||<frac|n<rsub|2>*cos
|
|||
|
\<theta\><rsub|<text|i>>-n<rsub|1>*cos
|
|||
|
\<theta\><rsub|<text|t>>|n<rsub|2>*cos
|
|||
|
\<theta\><rsub|<text|i>>+n<rsub|1>*cos
|
|||
|
\<theta\><rsub|<text|t>>>|\|><rsup|2>>
|
|||
|
</equation*>
|
|||
|
|
|||
|
Enfin, comme illustr<74> sur le diagramme, on combine ces classes pour en
|
|||
|
faire des objets compl<70>tements d<>finis : par exemple
|
|||
|
<verbatim|ObjetLigne_Milieux>, qui est un dioptre plan, h<>rite des classes
|
|||
|
<verbatim|ObjetCourbe_Milieux> et <verbatim|ObjetLigne>.<new-dpage>
|
|||
|
|
|||
|
Les <20>crans (d<>finis dans <verbatim|Ecran.h>) accumulent les rayons
|
|||
|
incidents et calculent une intensit<69> moyenne pour afficher ou enregistrer
|
|||
|
le r<>sultat. On utilise surtout <verbatim|EcranLigne_Multi>, qui est une
|
|||
|
matrice (<name|1d>) de pixels et qui h<>rite de <verbatim|ObjetLigne>.
|
|||
|
|
|||
|
<subsubsection|Sc<53>ne>
|
|||
|
|
|||
|
La logique de la propagation des rayons est impl<70>ment<6E>e dans la classe
|
|||
|
<verbatim|Scene> (<verbatim|Scene.h>/<verbatim|Scene.cpp>), qui stocke les
|
|||
|
sources et les objets de fa<66>on polymorphique
|
|||
|
(<verbatim|std::vector\<less\>std::shared_ptr\<less\>Objet\<gtr\>\<gtr\>>).
|
|||
|
Pour illuminer / former une image, on appelle la m<>thode
|
|||
|
<verbatim|emission_propagation()> qui lance les rayons <20> partir des
|
|||
|
sources. Pour chaque rayon, la m<>thode <verbatim|propagation_recur(Rayon)>
|
|||
|
est appel<65>e. Cette m<>thode effectue les tests d'interception et la
|
|||
|
r<>-<2D>mission de fa<66>on r<>cursive. Sch<63>matiquement, on a
|
|||
|
|
|||
|
<\indent>
|
|||
|
<\wide-tabular>
|
|||
|
<tformat|<cwith|1|1|1|1|cell-tborder|0ln>|<cwith|1|1|1|1|cell-bborder|0ln>|<cwith|1|1|1|1|cell-lborder|1ln>|<cwith|1|1|1|1|cell-rborder|0ln>|<cwith|1|1|1|1|cell-lsep|10pt>|<cwith|1|1|1|1|cell-background|#F5F5F5>|<table|<row|<\cell>
|
|||
|
<\compact>
|
|||
|
<\verbatim>
|
|||
|
<\small>
|
|||
|
void Scene::propagation_recur (rayon) {
|
|||
|
|
|||
|
\ \ \ \ rayons_re_emis = interception_re_emission(rayon);
|
|||
|
|
|||
|
\ \ \ \ for (ray : rayons_re_emis)\
|
|||
|
|
|||
|
\ \ \ \ \ \ \ \ propagation_recur(ray);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
std::vector\<less\>Rayon\<gtr\> Scene::interception_re_emission
|
|||
|
(ray) {
|
|||
|
|
|||
|
\ \ \ \ <samp|Teste <verbatim|objet-\<gtr\>essai_intercept(ray)>
|
|||
|
sur tous les objets de la sc<73>ne et s<>lectionne le premier>
|
|||
|
|
|||
|
\ \ \ \ \ \ <samp|objet sur le chemin du rayon.>
|
|||
|
|
|||
|
\ \ \ \ objet_le_plus_proche-\<gtr\>re_emit(ray,
|
|||
|
intercept_struct);
|
|||
|
|
|||
|
}
|
|||
|
</small>
|
|||
|
</verbatim>
|
|||
|
</compact>
|
|||
|
</cell>>>>
|
|||
|
</wide-tabular>
|
|||
|
</indent>
|
|||
|
|
|||
|
(cf.<nbsp>figure page 3). Les rayons sont ainsi propag<61>s sur la sc<73>ne
|
|||
|
jusqu'<27> ce qu'ils soient absorb<72>s par un <20>cran ou qu'ils soient d'intensit<69>
|
|||
|
n<>gligeable (<verbatim|Scene::intens_cutoff>). Une limite est fix<69>e pour
|
|||
|
<20>viter les r<>cursion infinies (par exemple avec une r<>flexion interne
|
|||
|
totale dans une lame).
|
|||
|
|
|||
|
Enfin, la m<>thode <verbatim|dessiner_scene()> est appel<65>e pour afficher
|
|||
|
tous les objets de la sc<73>ne dans la fen<65>tre. Tant que rien ne bouge dans la
|
|||
|
sc<73>ne, on r<>p<EFBFBD>te ce processus (une <em|frame>) autant que possible pour
|
|||
|
avoir un r<>sultat de moins en moins bruit<69> sur les <20>crans (merci au
|
|||
|
th<74>or<6F>me central limite).
|
|||
|
|
|||
|
<subsubsection|Divers>
|
|||
|
|
|||
|
La classe <verbatim|SceneTest> <20>tend <verbatim|Scene> et regroupe tout le
|
|||
|
code ind<6E>pendant du reste et qu'on trouverait typiquement dans les
|
|||
|
<verbatim|main()>, mais pas assez g<>n<EFBFBD>rique pour <20>tre dans la classe
|
|||
|
<verbatim|Sc<53>ne> : cr<63>ation des fen<65>tres <name|sfml>, de quelques objets
|
|||
|
courants, d'une lentille et d'un <20>cran pour former une image, <text-dots>
|
|||
|
|
|||
|
Le code est fourni avec 4 sc<73>nes d<>monstratives utilisant
|
|||
|
<verbatim|SceneTest> : <verbatim|main_milieux.cpp> (qu'on pourra regarder),
|
|||
|
<verbatim|main_brouillard.cpp>, <verbatim|main_store.cpp>,
|
|||
|
<verbatim|main_diffus_test.cpp>, et qu'on peut faire tourner avec
|
|||
|
<verbatim|make milieux>, <verbatim|make brouillard>, <verbatim|make store>,
|
|||
|
et <verbatim|make diffus_test> respectivement.
|
|||
|
|
|||
|
<\compact>
|
|||
|
Quelques remarques finales :
|
|||
|
|
|||
|
<\itemize-dot>
|
|||
|
<item>Tous les attributs de classes qui ne sont pas associ<63>s <20> des
|
|||
|
contraintes/invariants et qui sont susceptibles d'<27>tre utiles <20>
|
|||
|
l'utilisateur de la classe sont publiques. L'encapsulation, ce n'est
|
|||
|
pas emb<6D>ter l'utilisateur avec des getters, c'est prot<6F>ger
|
|||
|
l'utilisateur contre des b<>tises.
|
|||
|
|
|||
|
<item>L'extensibilit<69> et la clart<72> a <20>t<EFBFBD> pr<70>f<EFBFBD>r<EFBFBD>e <20> la performance
|
|||
|
quand le choix se posait.
|
|||
|
|
|||
|
<item>Lorsque les constructeurs par copie et d'affectation ne sont pas
|
|||
|
d<>clar<61>s, c'est qu'on laisse le compilateur g<>n<EFBFBD>rer celui par d<>faut,
|
|||
|
ou, lorsque marqu<71> <em|deleted> dans une classe parent, aucun.
|
|||
|
</itemize-dot>
|
|||
|
</compact>
|
|||
|
|
|||
|
<\wide-tabular>
|
|||
|
<tformat|<cwith|1|-1|1|-1|cell-valign|t>|<cwith|1|1|2|2|cell-lsep|10pt>|<cwith|1|1|1|1|cell-tsep|10pt>|<table|<row|<\cell>
|
|||
|
<subsection|Conclusion>
|
|||
|
|
|||
|
On reproduit tout <20> fait de nombreux effets d'optique g<>om<6F>trique que
|
|||
|
l'on connait bien : lentilles <20>paisses pas tout <20> fait stigmatiques et
|
|||
|
avec des aberrations chromatiques, fibres optiques<text-dots>
|
|||
|
|
|||
|
On obtient une illumination r<>aliste (toutefois gourmande en
|
|||
|
<name|cpu>) d'une sc<73>ne <name|2d>. La formation d'images <name|1d> (par
|
|||
|
exemple, <20> droite, un surface bleue diffusante avec reflet de la source
|
|||
|
ponctuelle l'<27>clairant) sont correctes mais un peu ennuyeuses. Cela
|
|||
|
donne envie d'<27>tendre le programme <20> une sc<73>ne <name|3d> (ce qui ne
|
|||
|
serait pas difficile) pour obtenir de vraies images <name|2d>.
|
|||
|
</cell>|<\cell>
|
|||
|
<image|<tuple|<#89504E470D0A1A0A0000000D494844520000004D000000FF0806000000B40B5BCE0000161B694343504943432050726F66696C6500005809AD58755816CFDA9E7DFB7DE97AE9EEEE96EE924E91EE6E240441040941524AE916149110831044544424544241444054500451EA5BFD7DD739E78FEFFCF7CD75EDCCBDB3CFCEEECE333BCF73DF00D01BBB868404202801080C8A08B3D0D3E4B0B377E0C07E0010200314000FA45CDDC34334CCCC8CC17F2DBB33B0355C2645FF8CF55FCDFEEF0B541E9EE1EE004066F065378F70F74018DF86B1997B4858040008148CB9A32342FE600118D386C12F08E3137FB0F73FF8CFBDB46EFF608FBF3656165AB0CD190070A4AEAE61DE001052E07E8E28776F781C422D0018EA200FDF2000287B60ACEAEEE30ADF47DC836D44020383614CCF036301B7FF18C7FB3FB0ABABDBBFC67475F5FE17FEE75BE03BE1076BFB868704B8C6FC3DF9FFAC020322E1F9FA5B10704DEA19646D09B7D4F021E015A66B01B744F850025A201804C04718E000C6F099F6FFD61CC01DEE8D84AF79C2755884E719784E00D00A0E8909F3F5F689E0D080BDE8C96110E42E26C22125212501C09F35F1C706806D8BBFBE8688E3FFEE73BC0480AC1A3C8F4FFFDD1702CF719B0C006C42FFEE13AC038005B66D53708F0C8BFA673CD49F060D08F05AA3058C800D700301200AA4801C5006EA40071802536005EC8113FCD63E2010FE9A68100F92402AC804974121280515A006348256700B74837B60003C024FC10B300DE6C02258011B600BEC827D0882B0101944033142EC102F240C49410A902AA403194316903DE4027943415024140F9D8732A13CA814AA829AA076E80E34008D4213D01B68095A87BE43BF114804298216C18AE043882314101A08238415E234C21B118A8845A420B211C5886AC47544176200F114318D58446C20769000498224223991A24805A416D214E980F4428621139019C8226435B20DD98B1C414E2217919F91BF5018140D8A03258A5246E9A3AC51EEA85054022A0B558A6A4475A1865093A825D416EA084D8666410BA395D006683BB4373A1A9D8A2E42D7A33BD1C3E869F40A7A1783C11031FC18798C3EC61EE38789C36461AE626E60FA31139865CC0E168B65C40A6355B0A658576C0436155B82BD8EEDC3BEC4AE60F7702438769C144E17E7800BC225E38A70CDB807B897B855DC3E9E12CF8B57C29BE23DF031F81C7C2DBE173F8E5FC1EF13A808FC04158215C18F90442826B4118609F3846D1212122E12451273125F927324C52437491E932C91FC22A5261522D52275248D24CD266D20ED277D43BA4D4646C647A64EE6401641964DD644F690EC2DD91E390DB918B901B907792279197917F94BF2AF14780A5E0A0D0A278A588A228A0E8A718ACF94784A3E4A2D4A57CA04CA32CA3B94AF2877A868A824A94CA902A9B2A89AA946A9D6A8B1D47CD43AD41ED429D435D40FA997699034DC345A34EE34E7696A698669566831B4FCB406B47EB499B4ADB4CF69B7E8A8E964E86CE8CED095D1DDA75B2422897C440362003187788B3843FC4DCF4AAF41EF499F4EDF46FF92FE270333833A83274306C30D866986DF8C1C8C3A8CFE8CB98CDD8C0B4C2826212673A668A66B4CC34C9F9969999599DD9933986F31CFB2205884582C58E2586A589EB1ECB0B2B1EAB186B096B03E64FDCC46645367F3632B607BC0B6CE4EC3AECAEECB5EC0DEC7FE89838E43832380A3986388638B9385539F3392B38AF339E73E173F97355732D70DAE056E02B702B7177701F720F7160F3B8F094F3C4F0BCF2C2F9E5781D787F70AEF08EF4F3E7E3E5BBE34BE6EBE357E067E03FE58FE16FE79013201358150816A8129418CA082A0BFE055C11742082159211FA132A1716184B09CB0AFF055E10911B488A2489048B5C82B5152510DD128D116D12531A298B158B258B7D857711E7107F15CF111F12309598900895A8939496A4943C964C95EC9EF524252EE52655253D264D2BAD289D23DD2DF6484653C65AEC9BC96A59135914D931D943D9493970B936B935B97E79177912F977FA540AB60A690A5F05811ADA8A998A8784FF197929C5284D22DA54D6551657FE566E5B513FC273C4FD49E5856E1527155A9525954E5507551AD545D54E3547355AB567BAFCEADEEA15EAFBEAA21A8E1A7715DE3ABA684669866A7E64F2D25ADB35AFDDA486D3DED0CEDE73AD43AD63AA53A6F75B974BD755B74B7F464F5E2F4FAF5D1FA46FAB9FAAF0C580DDC0D9A0CB60CE50DCF1A0E19911A591A951ABD3716320E33EE354198189AE49BCC9FE43D1974B2DB14981A98E69B2E98F19B859ADD35C7989B9997997FB490B488B718B1A4B174B66CB6DCB5D2B4CAB19AB316B08EB41EB4A1B071B469B2F969AB6D9B67BB68276E77D6EEA93D93BDAF7D8F03D6C1C6A1DE61E794CEA9C2532B8EB28EA98E33A7F94F9F393DEAC4E414E074DF99C2D9D5B9C305ED62EBD2EC72E06AEA5AEDBAE366E056EEB6E5AEE57EC57DC343DDA3C063DD53C533CF73D54BC52BCF6BCD5BC53BDF7BDD47CDA7C8E7B3AF966FA9EF373F7DBF0ABF9FFEA6FE0DFEC701B601370271812E817782A883FC838682D982CF044F840887A4862C862A8516866E851985D58743E1A7C37B2268E1E0FB2C5220F242E452946A5459D45EB44D74C719AA3341679EC508C5A4C7ACC6EAC6D6C5A1E2DCE306E339E393E297CE6A9CAD4A8012DC120613B913531257CEE99D6B4C2224F9278D254B24E725FF386F7BBE378535E55CCAF205BD0B2DA9E4A961A9AFD294D32A2EA22EFA5E7C9E2E9D5E927E94E191F1245322B328F320CB3DEBC925C94BC5978EB3BDB29FE7C8E55CBB8CB91C74792
|
|||
|
</cell>>>>
|
|||
|
</wide-tabular>
|
|||
|
</body>
|
|||
|
|
|||
|
<\initial>
|
|||
|
<\collection>
|
|||
|
<associate|page-medium|paper>
|
|||
|
</collection>
|
|||
|
</initial>
|
|||
|
|
|||
|
<\references>
|
|||
|
<\collection>
|
|||
|
<associate|auto-1|<tuple|1|1>>
|
|||
|
<associate|auto-2|<tuple|2|1>>
|
|||
|
<associate|auto-3|<tuple|2.1|3>>
|
|||
|
<associate|auto-4|<tuple|1|3>>
|
|||
|
<associate|auto-5|<tuple|2.2|5>>
|
|||
|
<associate|auto-6|<tuple|2.3|5>>
|
|||
|
<associate|auto-7|<tuple|3|5>>
|
|||
|
<associate|footnote-1|<tuple|1|1>>
|
|||
|
<associate|footnote-2|<tuple|2|1>>
|
|||
|
<associate|footnr-1|<tuple|1|1>>
|
|||
|
<associate|footnr-2|<tuple|2|1>>
|
|||
|
</collection>
|
|||
|
</references>
|
|||
|
|
|||
|
<\auxiliary>
|
|||
|
<\collection>
|
|||
|
<\associate|figure>
|
|||
|
<tuple|normal|<\surround|<hidden-binding|<tuple>|1>|>
|
|||
|
Sc<53>nario typique (celui de <with|font-family|<quote|tt>|language|<quote|verbatim>|Scene::interception_re_emission>)
|
|||
|
d'utilisation des objets.
|
|||
|
</surround>|<pageref|auto-4>>
|
|||
|
</associate>
|
|||
|
<\associate|toc>
|
|||
|
<with|par-left|<quote|1tab>|1.<space|2spc>Objectifs et m<>thodes
|
|||
|
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
|
|||
|
<no-break><pageref|auto-1>>
|
|||
|
|
|||
|
<with|par-left|<quote|1tab>|2.<space|2spc>Structure du code
|
|||
|
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
|
|||
|
<no-break><pageref|auto-2>>
|
|||
|
|
|||
|
<with|par-left|<quote|2tab>|2.1.<space|2spc>Objets
|
|||
|
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
|
|||
|
<no-break><pageref|auto-3>>
|
|||
|
|
|||
|
<with|par-left|<quote|2tab>|2.2.<space|2spc>Sc<53>ne
|
|||
|
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
|
|||
|
<no-break><pageref|auto-5>>
|
|||
|
|
|||
|
<with|par-left|<quote|2tab>|2.3.<space|2spc>Divers
|
|||
|
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
|
|||
|
<no-break><pageref|auto-6>>
|
|||
|
|
|||
|
<with|par-left|<quote|1tab>|3.<space|2spc>Conclusion
|
|||
|
<datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.2fn>.<space|0.2fn>>>>>|<htab|5mm>>
|
|||
|
<no-break><pageref|auto-7>>
|
|||
|
</associate>
|
|||
|
</collection>
|
|||
|
</auxiliary>
|