Centrale Informatique Commune MP PC PSI TSI 2021Sujet, corrigé et rapport du jury
Lancer de rayons
- Programmation en Python
- Structures de données et tableaux numpy
- Bases de données et langage SQL
- Complexité algorithmique
- Géométrie vectorielle
Téléchargements
Présentation du sujet
Lancer de rayons : génération d'une image 2D à partir d'une scène 3D de sphères éclairéesAfficher ou masquer la section
Présentation du sujet
Le sujet propose de programmer un algorithme de lancer de rayons pour générer une image bidimensionnelle à partir d'une scène en trois dimensions contenant des sphères éclairées par des sources lumineuses. Il combine géométrie, lois physiques de l'optique, gestion d'une base de données de la scène et écriture d'algorithmes en Python, avec quelques questions de complexité.
- 1Partie I : géométriepremière annéeMise en place des outils géométriques nécessaires à la représentation d'une scène et des rayons lumineux.
- 2Partie II : optiquepremière annéeLois physiques de visibilité, de diffusion et de réflexion régissant les rayons lumineux.
- 3Partie III : enregistrement des scènespremière annéeConception d'une structure de base de données adaptée à la gestion des scènes, avec des requêtes SQL.
- 4Partie IV : lancer de rayonspremière annéeÉcriture de l'algorithme de lancer de rayons et étude de sa complexité.
- 5Partie V : améliorationspremière annéeQuelques améliorations possibles de l'algorithme, dont la prise en compte de la réflexion.
L'épreuve en chiffres
Moyenne 8,98 / 20 · écart-type 4,42 · 4 899 présents · où vous situez-vous ?Afficher ou masquer la section
L'épreuve en chiffres
- Moyenne
- 8,98/ 20
- Écart-type
- 4,42
- Présents
- 4 899
- Coefficient
- 6
- Durée
- 3 h
- 1er quartile
- 6
- Médiane
- 8,6
- 3e quartile
- 12
Votre note sur 20 à ce sujet, en conditions de concours.
Source : document officiel du concours, épreuve du 23 avril 2021. Notes publiées par le concours (après harmonisation le cas échéant). Courbe : estimation par une loi normale.
Ce qu'a observé le jury
5 erreurs relevéesNon-respect du typage des fonctions · Complexités annoncées sans justification · Syntaxe SQL et jointures approximativesAfficher ou masquer la section
Ce qu'a observé le jury
5 erreurs relevéesLe jury observe que les connaissances informatiques semblent globalement acquises, avec une maîtrise variable des langages Python et SQL. La moitié des copies corrigées aborde près de 75% des questions, tandis qu'un très faible pourcentage en traite moins de 20%.
Les erreurs les plus sanctionnées
- 1Non-respect du typage des fonctionsQ1, Q2
Certaines réponses renvoient un type différent de celui attendu, par exemple une liste au lieu d'un tableau numpy, ou un vecteur au lieu d'un flottant.
- 2Complexités annoncées sans justificationQ23, Q24
Trop de candidats annoncent une complexité sans la justifier, alors qu'une complexité quadratique doit s'appuyer par exemple sur deux boucles imbriquées.
- 3Syntaxe SQL et jointures approximativesQ14, Q16
Les questions sur les bases de données sont quasi systématiquement abordées, mais peu de candidats obtiennent tous les points en raison d'une syntaxe SQL parfois approximative et d'une maîtrise insuffisante des jointures.
- 4Annexe non exploitéeQ14
La fonction EXTRACT, définie dans l'annexe et nécessaire à l'écriture d'une requête, n'a été utilisée que par très peu de candidats.
- 5Initialisation de variable oubliée ou incorrecteQ21, Q22, Q27
La variable de sortie est souvent mal initialisée, par exemple un tableau (N, N) au lieu de (N, N, 3), quand l'initialisation n'est pas simplement oubliée.
Ce qui a été bien réussi
- Les compétences en programmation élémentaire semblent acquises chez le plus grand nombre de candidats.
- Quelques candidats rendent des copies d'excellente qualité.
- Les codes sont globalement syntaxiquement corrects et lisibles.
Conseils du jury
- Respecter le type des objets manipulés et du résultat renvoyé par chaque fonction.
- Justifier toute estimation de complexité avec les notations strictes de l'énoncé.
- Lire l'intégralité du sujet, y compris les annexes, pour repérer les fonctions utiles comme EXTRACT.
- S'interroger sur l'organisation logique du code avant de l'écrire, pour éviter les calculs redondants.
Synthèse rédigée par WikiPrépa à partir du rapport officiel du jury (à télécharger en PDF). Les citations sont extraites du rapport.
Ces sujets peuvent vous intéresser
Lecture du sujet en ligne
L'énoncé complet, avec les formules et les figures, sans ouvrir le PDF.Afficher ou masquer la section
Lecture du sujet en ligne
Lancer de rayons
Et qu'au contraire les chats voient de nuit par le moyen des rayons qui tendent de leurs yeux vers les objets.
- René Descartes, Discours de la méthode - La dioptrique(1637)
}

De nombreuses questions sont indépendantes, il est toutefois demandé de les traiter dans l'ordre.
Les seuls langages informatiques autorisés dans cette épreuve sont Python et SQL. Pour répondre à une question, il est possible, et souvent souhaitable, de faire appel aux fonctions définies dans les questions précédentes.
Les modules math et numpy ont été rendus accessibles grâce à l'instruction
import math, numpy as np
Dans tout le sujet, le terme «liste» désigne une valeur de type list. Le terme «tableau» désigne une valeur de type np.ndarray. Enfin le terme «séquence» désigne une suite finie indiçable et itérable.
- Indiçable signifie que les éléments sont accessibles par des indices, seq[0] désignant le premier élément de la séquence seq.
- Itérable signifie que la séquence peut être parcourue dans une boucle par for element in seq: ...
Les entêtes des fonctions demandées sont annotés pour préciser les types des paramètres et du résultat. Ainsi,
def uneFonction(n:int, X:[float], c:str, u) -> (np.ndarray, int):
signifie que la fonction uneFonction prend quatre paramètres
Il n'est pas demandé aux candidats d'annoter leurs fonctions, la rédaction pourra commencer par
def uneFonction(n, X, c, u):
Une liste de fonctions potentiellement utiles est fournie à la fin du sujet.
I Géométrie
Tout point ou vecteur de l'espace est représenté en Python par le tableau de ses trois coordonnées cartésiennes, de type float. Pour faciliter la compréhension, un tel tableau est considéré de type point quand il désigne un point et de type vecteur quand il désigne un vecteur: np.array([0.,0.,0.]) est considéré de type point quand il représente le point
Beaucoup d'opérations classiques sur les vecteurs se transposent simplement dans la syntaxe de numpy. Si
Quand il n'y a pas de confusion possible, un objet mathématique est assimilé à sa représentation en Python. Ainsi, par exemple, «la fonction
On rappelle que la valeur du cosinus de l'angle formé par deux vecteurs unitaires correspond à la valeur de leur produit scalaire. Ainsi, si
Q 1. Écrire une fonction d'entête
def
qui prend deux points en paramètre et renvoie le vecteur
Q 2. Écrire une fonction d'entête
def ps(v1:vecteur, v2:vecteur) -> float:
qui prend en paramètres deux vecteurs
Q 3. Écrire une fonction d'entête
def norme(v:vecteur) -> float:
qui prend en paramètre un vecteur
Q 4. Écrire une fonction d'entête
def unitaire(v:vecteur) -> vecteur:
qui prend en paramètre un vecteur
On utilise dans ce sujet le modèle du rayon lumineux de l'optique géométrique. Un rayon lumineux issu du point
Ainsi, en définissant
Q 5. Que font les fonctions pt, dir et ra ci-dessous?
def pt(r:rayon, t:float) -> point:
assert t >= 0
(S, u) = r
return S + t * u
def dir(A:point, B:point) -> vecteur:
return unitaire(vec(A, B))
def ra(A:point, B:point) -> rayon:
return A, dir(A, B)
Q 6. Écrire une fonction d'entête
def
qui renvoie la sphère de centre
Q 7. Montrer qu'une droite passant par le point A de vecteur directeur
Q 8. Écrire une fonction d'entête
def intersection(r:rayon, s:sphère) -> (point, float) or None:
qui renvoie le premier point de la sphère
II Optique
Pour toute la suite, on a défini les variables globales
noir = np.array([0., 0., 0.])
blanc = np.array([1., 1., 1.])
II.A - Visibilité
Q 10. Écrire une fonction booléenne, d'entête
def au_dessus(s:sphère, P:point, src:point) -> bool:
Q 11. On considère une scène contenant plusieurs sphères et une source lumineuse. Pour que la source soit visible d'un point
def visible(obj:[sphère], j:int, P:point, src:point) -> bool:
II.B - Diffusion

def couleur_diffusée(r:rayon, Cs:couleur, N:vecteur, kd:couleur) -> couleur:
qui renvoie la couleur de la lumière diffusée par le point
II.C - Réflexion
-
u⃗, w⃗ etN⃗ sont coplanaires;
− (u⃗ + w⃗) ⋅ N⃗ = 0 , ce qui correspond àθ^′ = θ .
Q 13. Écrire une fonction d'entête
def rayon_réfléchi(s:sphère, P:point, src:point ) -> rayon:
qui renvoie le rayon réfléchi par le point P de la sphère s en provenance de la sourceS placée en src. Le résultat est le couple (P, w⃗ ) représentant le rayon émergent. La sourceS est supposée visible deP .
III Enregistrement des scènes
.jpg)
- la table Scene répertorie les scènes
- sc_id identifiant (entier arbitraire) de la scène (clé primaire)
- sc_creation date de création de la scène
- sc_modif date de dernière modification de la scène
- sc_nom nom de la scène
- la table Couleur définit les couleurs utilisées
- co_id identifiant (entier arbitraire) de la couleur (clé primaire)
- co_rouge valeur de la composante rouge (dans l'intervalle
[0, 1] ) - co_vert valeur de la composante verte (dans l'intervalle
[0, 1] ) - co_bleu valeur de la composante bleue (dans l'intervalle
[0, 1] ) - la table Sphere liste les sphères utilisées pour construire les scènes
- sp_id identifiant (entier arbitraire) de la sphère (clé primaire)
- sp_rayon rayon de la sphère
- sp_kd coefficients de diffusion de la sphère (référence dans la table Couleur)
- sp_kr coefficient de réflexion de la sphère (cf. partie V)
- la table Ponctuelle répertorie les sources ponctuelles disponibles
- po_id identifiant (entier arbitraire) de la source ponctuelle (clé primaire)
- co_id couleur de la source (référence dans la table Couleur)
- po_nom nom de la source
- la table Objet fait le lien entre les scènes et les objets qu'elles contiennent, ses deux premières colonnes constituent sa clé primaire
- sc_id identifiant de la scène
- ob_id identifiant de l'objet
- ob_x, ob_y, ob_z coordonnées du centre de l'objet dans la scène considérée
- la table Source indique quelles sont les sources qui éclairent chaque scène, ses deux premières colonnes constituent sa clé primaire
- sc_id identifiant de la scène
- so_id identifiant de la source
- so_x, so_y, so_z coordonnées de la source dans la scène considérée
Q 15. Écrire une requête
Q 16. Écrire une requête SQL qui liste l'identifiant, les coordonnées du centre et le rayon de toutes les sphères contenues dans la scène dont le nom est woodbox. On suppose qu'une seule scène possède ce nom.
Il est possible en SQL de définir des fonctions utilisateur qui s'utilisent comme les fonctions SQL pré-définies.
On dispose d'une fonction utilisateur booléenne de signature OCCULTE(sc_id, objr_id, so_id, objo_id) où sc_id, objr_id, so_id et objo_id sont les identifiants respectifs d'une scène, d'un objet de cette scène dit « récepteur », d'une source de cette scène et d'un autre objet de la scène dit «occultant ». La fonction renvoie TRUE si l'objet occultant projette son ombre sur l'objet récepteur lorsqu'il est éclairée par la source considérée.
Q 17. Écrire une requête
IV Lancer de rayons
- Objet est une liste des
n_o objets (sphères de type sphère) contenues dans la scène à représenter ; - KdObj est une liste de
n_o tableaux de type couleur représentant les coefficients de diffusion des sphères, KdObj[i] est associé à la sphère Objet [i] ; - Source est une liste de
n_s points (de type point) donnant l'emplacement desn_s sources lumineuses (ponctuelles) qui éclairent la scène à représenter ; - ColSrc est une liste de
n_s couleurs,ColSrc[i] représente la couleur de la source placée en Source [i].
même chemin pour joindre 2 points

Il sépare les objets de la scène, placés dans le demi espace
IV.A - Écran
Q 18. Écrire une fonction d'entête
def grille(i:int, j:int) -> point:
qui renvoie les coordonnées cartésiennes du point
Q 19. Écrire une fonction d'entête
def rayon_écran(omega:point, i:int, j:int) -> rayon:
qui renvoie le rayon issu du point omega et passant par
IV.B - Couleur d'un pixel
On considère un point
Q 20. Écrire une fonction d'entête
def interception(r:rayon) -> (point, int) or None:
qui prend en paramètre un rayon
Q 21. Écrire une fonction d'entête
def couleur_diffusion(P:point, j:int) -> couleur:
qui renvoie la couleur diffusée par le point P appartenant à la sphère Objet [j]. Si aucune source n'éclaire
IV.C - Constitution de l'image
def lancer(omega:point, fond:couleur) -> image:
qui génère l'image associée à la scène. Si un rayon n'intercepte aucun objet, le pixel correspondant est de couleur fond.
IV.D - Complexités
Q 23. Calculer la complexité temporelle de la fonction lancer dans le meilleur des cas en caractérisant la situation correspondante.
Q 24. Calculer la complexité temporelle de la fonction lancer dans le pire des cas en caractérisant la situation correspondante.
V Améliorations
V.A - Prise en compte de la réflexion
Q 25. Écrire une fonction d'entête
def réflexions(r:rayon, rmax:int) -> [(point, int)]:
qui renvoie une liste de couples
Le pouvoir réfléchissant d'un objet est caractérisé par un coefficient de réflexion
En tenant compte des phénomènes de diffusion et de réflexion, la couleur
Q 26. Écrire une fonction d'entête
def couleur_perçue(r:rayon, rmax:int, fond:couleur) -> couleur:
qui renvoie la couleur du premier point de la scène rencontré par le rayon
Q 27. Écrire une fonction d'entête
def lancer_complet(omega:point, fond:couleur, rmax:int) -> image:
qui construit l'image de la scène en tenant compte des diffusions et des réflexions.
Q 28. Exprimer la nouvelle complexité dans le pire cas.
V.B - Une optimisation
- IdObj telle que IdObj[i] soit l'identifiant dans la base de données (ob_id) de la sphère Objet [i] ;
- IdSrc telle que IdSrc[i] soit l'identifiant dans la base de données (so_id) de la source Source[i].
def table_risque(risque:[[int, int, int]]) -> [[[int]]]:
qui prend en paramètre une liste de triplets correspondant au résultat de la requête SQL de la question 17 et construit une liste de listes de listes d'entiers telle que, si res est le résultat de la fonction, res [i] [j] donne la liste (éventuellement vide) des indices des objets susceptibles de masquer la source Source [j] pour un point de l'objet Objet [i].
Q 30. Le résultat de la fonction table_risque est conservé dans la variable globale TableRisque. Écrire la fonction visible_opt d'entête
def visible_opt(j:int, k:int, P:point) -> bool:
qui prend en paramètres l'indice
Opérations et fonctions disponibles en Python et en SQL
Constantes
- math.inf, np.inf correspondent à
+ ∞ , n'importe quel nombre est strictement inférieur à cette valeur.
Fonctions Python diverses
- range(n) itérateur sur les n premiers entiers (
[ [0, n − 1] ] ).
list(range(5))→ [0, 1, 2, 3, 4] . - range(
d, f, p ) oùd, f et p sont des entiers, itérateur sur les entiers (r_i = d + ip|r_i < f)_(i ∈ ℕ) sip > 0 et(r_i = d + ip|r_i > f)_(i ∈ ℕ) sip < 0 . Le paramètre p est optionnel avec une valeur par défaut de 1 .
list (range(1, 5)) → [1, 2, 3, 4] ; list (range(20, 10, − 2)) → [20, 18, 16, 14, 12] . - math.sqrt(x) calcule la racine carrée du nombre x.
Opérations sur les listes
- len(L) donne le nombre d'éléments de la liste L .
- L1 + L2 construit une liste constituée de la concaténation des listes L1 et L2.
-
e inL ete not inL déterminent si l'objet e figure dans la listeL . Ces opérations ont une complexité temporelle enO(len(L)) . - L.append(e) ajoute l'élément e à la fin de la liste L.
- L.index(e) renvoie le plus petit entier i tel que
L[i] = e. Lève l'exception ValueError si l'élémente n'apparait pas dans la liste. Cette opération a une complexité temporelle enO(len(L)) . - L.sort() trie en place la liste L (qui est donc modifiée) en réordonnant ses éléments dans l'ordre croissant.
Opérations sur les tableaux (np.ndarray)
- np.array(s, dtype) crée un nouveau tableau contenant les éléments de la séquence
s . La taille de ce tableau est déduite du contenu des . Le paramètre optionnel dtype précise le type des éléments du tableau créé. - np.empty(n, dtype), np.empty((n, m), dtype) crée respectivement un tableau à une dimension de n éléments et un tableau à
n lignes etm colonnes dont les éléments, de valeurs indéterminées, sont de type dtype. Si le paramètre dtype n'est pas précisé, il prend la valeur float. - np.zeros(n, dtype), np.zeros((n, m), dtype) fonctionne comme np.empty en initialisant chaque élément à la valeur zéro pour les types numériques ou False pour les types booléens.
- np.sum(a) ou a.sum() renvoie la somme des éléments du tableau a.
- np.inner(
a, b ) calcule la somme des produits terme à terme dans le cas où a et b sont deux tableaux à une dimension de même taille. - np.all(a) vaut True si tous les éléments du tableau a ont une valeur logique «vrai».
- np.any(a) vaut True si au moins un des éléments du tableau a a une valeur logique «vrai».
SQL
- SELECT ... FROM t1 JOIN t2 ON ... effectue une requête sur le résultat du produit cartésien entre les tables t1 et t2 restreint par la condition indiquée. Par exemple t1.a
= t2.b permet de limiter le résultat aux lignes pour lesquelles la colonne a de la table t 1 est égale à la colonne b de la table t 2 . - SELECT ... FROM t AS t1 JOIN t AS t2 ON ... effectue une requête sur le résultat du produit cartésien de la table t avec elle-même restreint par la condition indiquée. Le premier exemplaire de la table t est désigné par t1 et le second par t2.
- La fonction EXTRACT (part FROM t ) extrait un élément de t , expression de type date, time, timestamp (jour et heure) ou interval (durée). part peut prendre les valeurs year, month, day (jour dans le mois), doy (jour dans l'année), dow (jour de la semaine), hour, etc.
- Les fonctions d'agrégation
SUM(e), AVG(e), MAX(e), MIN(e), COUNT(e), COUNT(∗) calculent respectivement la somme, la moyenne arithmétique, le maximum, le minium, le nombre de valeurs non nulles de l'expression e et le nombre de lignes pour chaque groupe de lignes défini par la cause GROUP BY. Si la requête ne comporte pas de clause GROUP BY le calcul est effectué pour l'ensemble des lignes sélectionnées par la requête.
^1 Exemple fourni avec le logiciel libre de lancer de rayons POV-Ray. Fichier woodbox.pov, POV-Ray scene file by Dan Farmer, sous licence Creative Commons Attribution-ShareAlike 3.0
Questions fréquentes
4 questionsSur quoi porte le sujet d'informatique commune Centrale MP-PC-PSI-TSI 2021 ?Afficher ou masquer la section
Questions fréquentes
4 questionsSur quoi porte le sujet d'informatique commune Centrale MP-PC-PSI-TSI 2021 ?
Il porte sur la programmation d'un algorithme de lancer de rayons permettant de générer une image à partir d'une scène 3D de sphères éclairées.
Faut-il bien connaître le SQL pour ce sujet informatique commune Centrale 2021 ?
Oui, une partie du sujet porte sur une base de données de la scène et demande d'écrire des requêtes SQL, notamment avec la fonction EXTRACT fournie en annexe.
Quelles sont les erreurs les plus fréquentes sur ce sujet d'informatique Centrale-Supélec 2021 ?
Le jury relève surtout un non-respect du typage des fonctions, des complexités annoncées sans justification et des requêtes SQL avec des jointures incorrectes.
Ce sujet Centrale informatique commune 2021 est-il faisable en première année ?
Le sujet fait très largement appel aux connaissances algorithmiques et pratiques du programme de première année.
Pas de description pour le moment
