# -*- coding: utf-8 -*- """ Corrigé Python - Bac NSI 2026 - Épreuve pratique - Sujet 9 Thème : modélisation 3D, objets, distances et estimation d'impression """ from __future__ import annotations from math import sqrt class Sommet: """Représente un sommet dans l'espace.""" def __init__(self, x: float, y: float, z: float) -> None: self.x = x self.y = y self.z = z def distance(self, s: "Sommet") -> float: """Renvoie la distance entre le sommet courant et le sommet s.""" return sqrt((self.x - s.x) ** 2 + (self.y - s.y) ** 2 + (self.z - s.z) ** 2) def __repr__(self) -> str: return f"Sommet({self.x}, {self.y}, {self.z})" class Face: """Représente une face par la liste de ses sommets.""" def __init__(self, sommets: list[Sommet]) -> None: self.sommets = sommets class Objet3D: """Représente un objet 3D composé de sommets et de faces.""" def __init__(self) -> None: self.sommets = [] self.faces = [] self.nom = "" def ajouter_sommet(self, x: float, y: float, z: float) -> None: self.sommets.append(Sommet(x, y, z)) def ajouter_face(self, liste_indices: list[int]) -> None: self.faces.append(Face([self.sommets[i] for i in liste_indices])) def sommets_adjacents(self, s1: Sommet, s2: Sommet) -> bool: """ Renvoie True si s1 et s2 sont deux sommets consécutifs d'une même face. Les arêtes ne sont pas orientées. """ for face in self.faces: n = len(face.sommets) for i in range(n): a = face.sommets[i] b = face.sommets[(i + 1) % n] if (a is s1 and b is s2) or (a is s2 and b is s1): return True return False def longueur_plus_longue_arete(self) -> float: max_longueur = 0.0 for s1 in self.sommets: for s2 in self.sommets: if self.sommets_adjacents(s1, s2): max_longueur = max(max_longueur, s1.distance(s2)) return max_longueur def volume_cube_englobant(self) -> float: return self.longueur_plus_longue_arete() ** 3 def transformer(self, rapport: float) -> None: """Multiplie les coordonnées de chaque sommet par rapport.""" for sommet in self.sommets: sommet.x *= rapport sommet.y *= rapport sommet.z *= rapport class Imprimante3D: """Représente une imprimante 3D.""" def __init__(self, remplissage: float, vitesse_extrusion: float) -> None: self.remplissage = remplissage self.vitesse_extrusion = vitesse_extrusion def estimation_impression(self, objet: Objet3D) -> float: """ Renvoie une estimation du temps d'impression en secondes. On accepte un taux de remplissage écrit sous forme 0.2 ou 20. """ taux = self.remplissage / 100 if self.remplissage > 1 else self.remplissage volume_impression = objet.volume_cube_englobant() * taux return volume_impression / self.vitesse_extrusion def construire_cube_test() -> Objet3D: cube = Objet3D() cube.ajouter_sommet(0, 0, 0) cube.ajouter_sommet(1, 0, 0) cube.ajouter_sommet(1, 1, 0) cube.ajouter_sommet(0, 1, 0) cube.ajouter_sommet(0, 0, 1) cube.ajouter_sommet(1, 0, 1) cube.ajouter_sommet(1, 1, 1) cube.ajouter_sommet(0, 1, 1) cube.ajouter_face([0, 1, 2, 3]) cube.ajouter_face([4, 5, 6, 7]) cube.ajouter_face([0, 1, 5, 4]) cube.ajouter_face([1, 2, 6, 5]) cube.ajouter_face([2, 3, 7, 6]) cube.ajouter_face([3, 0, 4, 7]) return cube def tests() -> None: s1 = Sommet(0, 0, 0) s2 = Sommet(3, 4, 0) assert s1.distance(s2) == 5 cube = construire_cube_test() assert cube.sommets_adjacents(cube.sommets[0], cube.sommets[1]) is True assert cube.sommets_adjacents(cube.sommets[0], cube.sommets[2]) is False assert cube.volume_cube_englobant() == 1 imprimante = Imprimante3D(20, 1.2) assert abs(imprimante.estimation_impression(cube) - (0.2 / 1.2)) < 1e-12 cube.transformer(2) assert cube.longueur_plus_longue_arete() == 2 print("Tous les tests du sujet 9 sont passés.") if __name__ == "__main__": tests()