@@ -413,33 +413,38 @@ def _draw_tubes(self, ax, drawn_surfaces, vis_args):
413413
414414 def _draw_motor (self , last_radius , last_x , ax , vis_args , plane = "xz" ):
415415 """Draws the motor from motor patches"""
416-
417- # Obtenir les patches (logique cluster/simple est dans la fonction ci-dessous)
416+
418417 motor_patches = self ._generate_motor_patches (ax , plane )
419418
420- # Dessiner les patches
421419 if not isinstance (self .rocket .motor , EmptyMotor ):
422-
420+
423421 if isinstance (self .rocket .motor , ClusterMotor ):
424- # Logique pour Cluster
422+
425423 for patch in motor_patches :
426424 ax .add_patch (patch )
427-
428- # Raccorder le tube au début (point z min) du cluster
425+
429426 if self .rocket .motor .positions :
430- # Trouve le z le plus proche de la coiffe
431- cluster_z_positions = [pos [2 ] for pos in self .rocket .motor .positions ]
432- z_connector = min (cluster_z_positions ) if self .rocket ._csys == 1 else max (cluster_z_positions )
433- self ._draw_nozzle_tube (last_radius , last_x , z_connector , ax , vis_args )
434-
427+
428+ cluster_z_positions = [
429+ pos [2 ] for pos in self .rocket .motor .positions
430+ ]
431+ z_connector = (
432+ min (cluster_z_positions )
433+ if self .rocket ._csys == 1
434+ else max (cluster_z_positions )
435+ )
436+ self ._draw_nozzle_tube (
437+ last_radius , last_x , z_connector , ax , vis_args
438+ )
439+
435440 else :
436- # Logique originale pour Moteur Simple
441+
437442 total_csys = self .rocket ._csys * self .rocket .motor ._csys
438443 nozzle_position = (
439- self .rocket .motor_position + self .rocket .motor .nozzle_position * total_csys
444+ self .rocket .motor_position
445+ + self .rocket .motor .nozzle_position * total_csys
440446 )
441-
442- # Ajouter la tuyère (logique originale)
447+
443448 nozzle = self .rocket .motor .plots ._generate_nozzle (
444449 translate = (nozzle_position , 0 ), csys = self .rocket ._csys
445450 )
@@ -448,104 +453,86 @@ def _draw_motor(self, last_radius, last_x, ax, vis_args, plane="xz"):
448453 outline = self .rocket .motor .plots ._generate_motor_region (
449454 list_of_patches = motor_patches
450455 )
451- # Ajouter l'outline en premier
456+
452457 ax .add_patch (outline )
453458 for patch in motor_patches :
454459 ax .add_patch (patch )
455460
456- self ._draw_nozzle_tube (last_radius , last_x , nozzle_position , ax , vis_args )
461+ self ._draw_nozzle_tube (
462+ last_radius , last_x , nozzle_position , ax , vis_args
463+ )
464+
457465 def _generate_motor_patches (self , ax , plane = "xz" ):
458466 """Generates motor patches for drawing"""
459467 motor_patches = []
460468 total_csys = self .rocket ._csys * self .rocket .motor ._csys
461469
462- # ################################################
463- # ## LOGIQUE D'AFFICHAGE POUR CLUSTER DE MOTEURS ##
464- # ################################################
465470 if isinstance (self .rocket .motor , ClusterMotor ):
466471 cluster = self .rocket .motor
467- all_sub_patches = [] # Pour l'outline global
468-
472+ all_sub_patches = [] # Pour l'outline global
473+
469474 for sub_motor , sub_pos in zip (cluster .motors , cluster .positions ):
470- # sub_pos est [x, y, z]
471- motor_longitudinal_pos = sub_pos [2 ] # Position Z du moteur
472-
473- # Déterminer le décalage (offset)
475+
476+ motor_longitudinal_pos = sub_pos [2 ]
477+
474478 offset = 0
475479 if plane == "xz" :
476- offset = sub_pos [0 ] # Coordonnée X
480+ offset = sub_pos [0 ]
477481 elif plane == "yz" :
478- offset = sub_pos [1 ] # Coordonnée Y
482+ offset = sub_pos [1 ]
479483
480- # `sub_total_csys` convertit un déplacement relatif au moteur
481- # en un déplacement relatif à la fusée.
482484 sub_total_csys = self .rocket ._csys * sub_motor ._csys
483-
484- # On réutilise la logique de SolidMotor, mais avec un offset
485+
485486 if isinstance (sub_motor , SolidMotor ):
486- current_motor_patches = [] # Patches pour CE moteur
487-
488- # Position Z du centre de masse des grains DANS LE REPERE FUSÉE
487+ current_motor_patches = []
488+
489489 grains_cm_pos = (
490490 motor_longitudinal_pos
491491 + sub_motor .grains_center_of_mass_position * sub_total_csys
492492 )
493493 ax .scatter (
494- grains_cm_pos .real , # Utiliser .real pour éviter ComplexWarning
495- offset ,
494+ grains_cm_pos .real ,
495+ offset ,
496496 color = "brown" ,
497- label = f"Grains CM ({ sub_pos [0 ]:.2f} , { sub_pos [1 ]:.2f} )" ,
497+ label = f"Grains CM ({ sub_pos [0 ]:.2f} , { sub_pos [1 ]:.2f} )" ,
498498 s = 8 ,
499499 zorder = 10 ,
500500 )
501501
502- # `translate` prend (pos_z, pos_y_offset)
503- # Ces fonctions utilisent le _csys interne du sub_motor (qui est 1)
504502 chamber = sub_motor .plots ._generate_combustion_chamber (
505503 translate = (grains_cm_pos .real , offset ), label = None
506504 )
507505 grains = sub_motor .plots ._generate_grains (
508506 translate = (grains_cm_pos .real , offset )
509507 )
510-
511- # Position Z de la tuyère DANS LE REPERE FUSÉE
508+
512509 nozzle_position = (
513510 motor_longitudinal_pos
514511 + sub_motor .nozzle_position * sub_total_csys
515512 )
516-
517- # ***** CORRECTION ICI *****
518- # On ne passe PAS de 'csys' !
519- # On laisse la fonction _generate_nozzle utiliser son
520- # propre _csys interne (qui est 1, tail_to_nose),
521- # car 'nozzle_position' est déjà la coordonnée absolue.
513+
522514 nozzle = sub_motor .plots ._generate_nozzle (
523515 translate = (nozzle_position .real , offset )
524516 )
525- # **************************
526-
517+
527518 current_motor_patches += [chamber , * grains , nozzle ]
528519 all_sub_patches .extend (current_motor_patches )
529520
530- # Créer un outline global pour tous les moteurs
531521 if all_sub_patches :
532- # Utiliser .plots du premier moteur pour la méthode
522+
533523 outline = self .rocket .motor .motors [0 ].plots ._generate_motor_region (
534524 list_of_patches = all_sub_patches
535525 )
536- motor_patches .append (outline ) # Mettre l'outline en premier
526+ motor_patches .append (outline ) # Mettre l'outline en premier
537527 motor_patches .extend (all_sub_patches )
538528
539- # #####################################
540- # ## LOGIQUE ORIGINALE (MOTEUR SIMPLE) ##
541- # #####################################
542529 elif isinstance (self .rocket .motor , SolidMotor ):
543530 grains_cm_position = (
544531 self .rocket .motor_position
545532 + self .rocket .motor .grains_center_of_mass_position * total_csys
546533 )
547534 ax .scatter (
548- grains_cm_position .real , # .real
535+ grains_cm_position .real , # .real
549536 0 ,
550537 color = "brown" ,
551538 label = "Grains Center of Mass" ,
@@ -554,10 +541,10 @@ def _generate_motor_patches(self, ax, plane="xz"):
554541 )
555542
556543 chamber = self .rocket .motor .plots ._generate_combustion_chamber (
557- translate = (grains_cm_position .real , 0 ), label = None # .real
544+ translate = (grains_cm_position .real , 0 ), label = None # .real
558545 )
559546 grains = self .rocket .motor .plots ._generate_grains (
560- translate = (grains_cm_position .real , 0 ) # .real
547+ translate = (grains_cm_position .real , 0 ) # .real
561548 )
562549
563550 motor_patches += [chamber , * grains ]
@@ -568,7 +555,7 @@ def _generate_motor_patches(self, ax, plane="xz"):
568555 + self .rocket .motor .grains_center_of_mass_position * total_csys
569556 )
570557 ax .scatter (
571- grains_cm_position .real , # .real
558+ grains_cm_position .real , # .real
572559 0 ,
573560 color = "brown" ,
574561 label = "Grains Center of Mass" ,
@@ -580,16 +567,16 @@ def _generate_motor_patches(self, ax, plane="xz"):
580567 translate = (self .rocket .motor_position , 0 ), csys = total_csys
581568 )
582569 chamber = self .rocket .motor .plots ._generate_combustion_chamber (
583- translate = (grains_cm_position .real , 0 ), label = None # .real
570+ translate = (grains_cm_position .real , 0 ), label = None # .real
584571 )
585572 grains = self .rocket .motor .plots ._generate_grains (
586- translate = (grains_cm_position .real , 0 ) # .real
573+ translate = (grains_cm_position .real , 0 ) # .real
587574 )
588575 motor_patches += [chamber , * grains ]
589576 for tank , center in tanks_and_centers :
590577 ax .scatter (
591- center [0 ].real , # .real
592- center [1 ].real , # .real
578+ center [0 ].real , # .real
579+ center [1 ].real , # .real
593580 color = "black" ,
594581 alpha = 0.2 ,
595582 s = 5 ,
@@ -603,8 +590,8 @@ def _generate_motor_patches(self, ax, plane="xz"):
603590 )
604591 for tank , center in tanks_and_centers :
605592 ax .scatter (
606- center [0 ].real , # .real
607- center [1 ].real , # .real
593+ center [0 ].real , # .real
594+ center [1 ].real , # .real
608595 color = "black" ,
609596 alpha = 0.2 ,
610597 s = 4 ,
@@ -672,17 +659,13 @@ def _draw_rail_buttons(self, ax, vis_args):
672659
673660 def _draw_center_of_mass_and_pressure (self , ax ):
674661 """Draws the center of mass and center of pressure of the rocket."""
675- # Draw center of mass and center of pressure
676-
677- # MODIFICATION 1: Récupérer le vecteur CM et extraire .z
662+
678663 cm_vector = self .rocket .center_of_mass (0 )
679- # On prend la partie réelle pour éviter les warnings
680- cm_z = float (cm_vector .z .real )
681-
682- # On suppose que le CM est sur l'axe pour le dessin 2D
664+
665+ cm_z = float (cm_vector .z .real )
666+
683667 ax .scatter (cm_z , 0 , color = "#1565c0" , label = "Center of Mass" , s = 10 )
684668
685- # MODIFICATION 2: Prendre la partie réelle du CP aussi
686669 cp_z = float (self .rocket .cp_position (0 ).real )
687670 ax .scatter (
688671 cp_z , 0 , label = "Static Center of Pressure" , color = "red" , s = 10 , zorder = 10
0 commit comments