
    Mi*                        S r SSKrSSKJrJrJrJrJrJ	r	  SSK
Jr   SS\S\S\S	\\   S
\\	   4
S jjrS\S\S
\\	   4S jr  SS\S\S\\4   S\S
\\	   4S jjrS\4S jr  SS	\S\S\S\\   4S jjrS rSS	\\   S
\\	   4S jjrg)z
inertia.py
-------------

Functions for dealing with inertia tensors.

Results validated against known geometries and checked for
internal consistency.
    N   )	ArrayLikeNDArrayNumberOptionalUnionfloat64)	multi_dotmassradiusheight	transformreturnc                     US-  US-  pT[         R                  " X-  S-  X-  S-  -   X-  S-  X-  S-  -   X-  S-  /5      nU[         R                  " S5      -  nUb  [        X75      nU$ )a  
Return the inertia tensor of a cylinder.

Parameters
------------
mass : float
  Mass of cylinder
radius : float
  Radius of cylinder
height : float
  Height of cylinder
transform : (4, 4) float
  Transformation of cylinder

Returns
------------
inertia : (3, 3) float
  Inertia tensor
            )nparrayeyetransform_inertia)r   r   r   r   h2r2diagonalinertias           i/var/www/eduai.edurigo.com/storigo/production/storigo_env/lib/python3.13/site-packages/trimesh/inertia.pycylinder_inertiar      s    , QY	xxi249/2i249/2Y!O	
H "G#I7N    c                 F    SUS-  -  U -  [         R                  " S5      -  $ )z
Return the inertia tensor of a sphere.

Parameters
------------
mass : float
  Mass of sphere
radius : float
  Radius of sphere

Returns
------------
inertia : (3, 3) float
  Inertia tensor
g?r   r   )r   r   )r   r   s     r   sphere_inertiar!   7   s%      &!)$t+bffQi77r   pointsweightsat_center_massc                     UcC  [         R                  " [        U 5      S[        [        U 5      5      -  [         R                  S9nO[        U[        [         R                  [        45      (       a7  [         R                  " [        U 5      [        U5      [         R                  S9nOQ[         R                  " U5      n[        U5      [        U 5      :w  a#  [        S[        U5       S[        U 5       35      e[         R                  " U [         R                  S9n [        U R                  5      S:w  d  U R                  S   S:w  a  [        SU R                   35      eU(       a  [         R                  " XS	S
9nX-
  nOU nUR                  u  pVnUS-  R                  u  pn
[         R                  " X-   U* U-  U* U-  U* U-  X-   U* U-  U* U-  U* U-  X-   /	[         R                  S9nX-  R                  SS9R                  S5      nU$ )am  
Calculate an inertia tensor for an array of point masses
at the center of mass.

Parameters
----------
points : (n, 3)
  Points in space.
weights : (n,) or number
  Per-point weight to use.
at_center_mass
  Calculate at the center of mass of the points, or if False
  at the original origin.

Returns
-----------
tensor : (3, 3)
  Inertia tensor for point masses.
g      ?dtypez#Weights must correspond to points! z != r   r   r   zPoints must be `(n, 3)` not r   )r#   axisr(   r   r   )r   fulllenfloatr	   
isinstanceintegerintr   
ValueError
asanyarrayshapeaverageTsumreshape)r"   r#   r$   center_mass
points_comxyzx2y2z2tensorstensors                r   points_inertiarB   J   s   0 
 ''#f+sU3v;-?'?rzzR	GeRZZ5	6	6''#f+uW~RZZH((7#w<3v;&5c'l^4F}U 
 ]]64F
6<<AaA!57~FGGjjqA)
 
 llGA!a-""JBB hh	1"q&1"q&1"q&"'A26A26A2627SjjG $$!$,44V<FMr   r   c                     [         R                  " U [         R                  S9n U R                  S:w  a  [	        S5      e[         R
                  R                  U 5      u  pUR                  nX4$ )a;  
Find the principal components and principal axis
of inertia from the inertia tensor.

Parameters
------------
inertia : (3, 3) float
  Inertia tensor

Returns
------------
components : (3,) float
  Principal components of inertia
vectors : (3, 3) float
  Row vectors pointing along the
  principal axes of inertia
r&   r*   zinertia tensor must be (3, 3)!)r   r2   r	   r3   r1   linalgeighr5   )r   
componentsvectorss      r   principal_axisrH      s[    $ mmG2::6G}}9:: ))..1J iiGr   inertia_tensorparallel_axisc           	      @   [         R                  " U [         R                  S9n U R                  S:X  a  U SS2SS24   nOU R                  S:X  a  U nO[	        S5      e[         R                  " U[         R                  S9nUR                  S:w  a  [	        S5      eU(       a  U R                  S:X  a$  [         R
                  " S[         R                  S9nO	U SS2S4   n[         R                  " US   S	-  US	   S	-  -   US
   * US   -  US
   * US	   -  /US
   * US   -  US
   S	-  US	   S	-  -   US   * US	   -  /US
   * US	   -  US   * US	   -  US
   S	-  US   S	-  -   //5      nXU-  -   n[        UR                  Xt/5      $ [        XAUR                  /5      $ )a  
 Transform an inertia tensor to a new frame.

 Note that in trimesh `mesh.moment_inertia` is *axis aligned*
 and at `mesh.center_mass`.

 So to transform to a new frame and get the moment of inertia at
 the center of mass the translation should be ignored and only
 rotation applied.

 If parallel axis is enabled it will compute the inertia
 about a new location.

 More details in the MIT OpenCourseWare PDF:
` MIT16_07F09_Lec26.pdf`


 Parameters
 ------------
 transform : (3, 3) or (4, 4) float
   Transformation matrix
 inertia_tensor : (3, 3) float
   Inertia tensor.
 parallel_axis : bool
   Apply the parallel axis theorum or not.
   If the passed inertia tensor is at the center of mass
   and you want the new post-transform tensor also at the
   center of mass you DON'T want this enabled as you *only*
   want to apply the rotation. Use this to get moment of
   inertia at an arbitrary frame that isn't the center of mass.

 Returns
 ------------
 transformed : (3, 3) float
   Inertia tensor in new frame.
r&   )r   r   Nr   r*   z#transform must be (3, 3) or (4, 4)!zinertia_tensor must be (3, 3)!r   r   r   )	r   r2   r	   r3   r1   zerosr   r
   r5   )r   rI   rJ   r   rotationaMaligned_inertias           r   r   r      s   V irzz:I& RaR!V$	F	">??]]>DNv%9::??f$"**-A "1"a% A HH1QqTQY&1!qteadlCA$1qtqy1Q4194qteadlCA$1!uqt|QqTQY1-BC
 )!83(**o@AAh

;<<r   c                 r   U R                   R                  5       nUS:  R                  5       (       a  gU[        R                  R                  U5      -  nU R                  nUR                  5       n[        R                  " [        R                  " X   5      5      nUS:  nUR                  5       (       a  US   nUSS nSXg4$ UR                  5       (       a]  U[        R                  " SS/SS//5      U      R                  5       nX(   nU[        R                  " SS/5      U      S   n	X)   nS	Xg4$ g)
ad  
Check whether a mesh has radial symmetry.

Returns
-----------
symmetry : None or str
     None         No rotational symmetry
     'radial'     Symmetric around an axis
     'spherical'  Symmetric around a point
axis : None or (3,) float
  Rotation axis or point
section : None or (3, 2) float
  If radial symmetry provide vectors
  to get cross section
gKH9)NNNg-C6?r   r   N	sphericalradial)principal_inertia_componentscopyanyr   rD   normprincipal_inertia_vectorsargsortabsdiffallr   flatten)
meshscalarvectororderr\   	diff_zeror(   sectionsection_index
axis_indexs
             r   radial_symmetryrg     s,   $ ..335F 	 biinnV,,F++FNNE
 66"''&-()DtI}} ay*D))	 bhhAB'89)DEMMO' 288RG,Y78;
!&&r   c                    U R                   nU R                  nUR                   Vs/ s H  oBU   PM	     nn[        R                  " U VVs/ s H_  u  pg[        X7   S5      (       d  M  X7   R                  [        R                  " [        R                  R                  U5      U5      5      PMa     snn[        R                  S9nUR                  SS9$ s  snf s  snnf )a  
Calculate the inertia of a scene about a specific frame.

Parameters
------------
scene : trimesh.Scene
  Scene with geometry.
transform : None or (4, 4) float
  Homogeneous transform to compute inertia at.

Returns
----------
moment : (3, 3)
  Inertia tensor about requested frame
moment_inertia_framer&   r   r)   )graphgeometrynodes_geometryr   r   hasattrri   dotrD   invr	   r6   )	scener   rj   geomsnnodesmatgmomentss	            r   scene_inertiarw   K  s    " KKENNE  %3343!1X3E4hh  	
ux!78 QEH))"&&s1CY*OP	

 jjG ;;A; 5	
s   CC
)A	C
)N)NT)FN)__doc__numpyr   typedr   r   r   r   r   r	   utilr
   r   r!   boolrB   rH   r   rg   rw    r   r   <module>r~      s+    G G  TX#
# #*0#=Ei=P#W#L8 8 8GG4D 8* /3DD4F*+D D W	DNI J  !	L=L=L= L= 6
	L=^FR HY$7  77CS  r   