Elaborar um código em qualquer linguagem de programação que faça a transformação vetorial entre os 3 sistemas de coordenadas (cartesiano, cilíndrico e esférico)
Passo 1
O que o enunciado pede: criar um código (em qualquer linguagem) que faça a transformação vetorial entre os três sistemas de coordenadas — cartesiano, cilíndrico e esférico — isto é, dada a representação das componentes de um vetor em um dos sistemas, devolver as componentes desse mesmo vetor em outro sistema.
Informações e convenções que vou usar (importante para não haver confusão):
Coordenadas cartesianas: (x,y,z) com base ortonormal \{\hat{\imath},\hat{\jmath},\hat{k}\}.
Coordenadas cilíndricas: (\rho,\varphi,z) com base local \{\hat{\rho},\hat{\varphi},\hat{z}\}, onde \varphi é o ângulo azimutal no plano xy medido a partir do eixo x no sentido anti-horário.
Coordenadas esféricas (convenção física): (r,\theta,\varphi) com base local \{\hat{r},\hat{\theta},\hat{\varphi}\}, onde \theta é o ângulo polar (medido a partir do eixo +z) e \varphi é o ângulo azimutal (mesma definição que em cilíndricas).
Observação importante: transformação “vetorial” significa transformar as componentes do vetor em relação às bases locais, não apenas transformar as coordenadas do ponto de aplicação. Como as bases dependem da posição (ângulos), é necessário conhecer a posição (ou pelo menos os ângulos) do ponto onde o vetor está definido para realizar a transformação.
O código deve tratar casos singulares (por exemplo r=0 ou \rho=0 em que \varphi ou \theta ficam indeterminados) de forma robusta (atribuir um ângulo arbitrário ou retornar aviso).
Passo 2
Transformação entre sistemas — relações fundamentais e como pensar nelas.
Relação entre as bases cartesiana e cilíndrica.
As unidades de base cilíndrica em termos das bases cartesianas valem:
Isto significa que, se um vetor tem componentes cartesianas (V_x,V_y,V_z) e componentes cilíndricas (V_\rho,V_\varphi,V_z) (note que V_z é o mesmo), então:
E a inversa (para voltar a cartesianas) é a transposta dessa matriz, porque as bases são mutuamente ortonormais.
Relação entre cilíndricas e esféricas (bases).
As bases esféricas podem ser expressas através das cilíndricas (lembrando que \rho = r\sin\theta e z=r\cos\theta, e que \hat{\varphi} coincide nos dois sistemas):
Como calcular os ângulos a partir de coordenadas cartesianas (útil no código):
\rho = \sqrt{x^2+y^2}.
\varphi = \operatorname{atan2}(y,x) — usar a função atan2 para obter o quadrante correto.
r = \sqrt{x^2+y^2+z^2}.
\theta = \operatorname{atan2}(\rho, z) ou \theta = \operatorname{arccos}\!\left(\dfrac{z}{r}\right) (usar atan2 evita divisão por zero se r=0).
Explicando devagar: a função \operatorname{atan2}(y,x) devolve o ângulo no intervalo (-\pi,\pi] e resolve o sinal de x e y, então é a escolha correta para \varphi. Para \theta, \operatorname{atan2}(\rho,z) dá o ângulo entre o vetor radial e o eixo z.
Passo 4
Casos singulares e cuidados práticos (muito importantes para o código de prova):
Se r = 0 (o vetor está na origem), \theta e \varphi são indeterminados: o vetor pode ser representado igualmente em qualquer direção. No código, adotaremos um tratamento consistente (por exemplo fixar \varphi=0, \theta=0 e tratar a transformação com cuidado).
Se \rho = 0 (no eixo z), \varphi é indeterminado; novamente fixar \varphi=0 é uma escolha prática.
Ao comparar a igualdade de floats, usar tolerância numérica (epsilon) para evitar divisões por zero.
Sempre trabalhar com radianos no código.
Passo 5
Um pequeno exemplo numérico (para fixar como aplicar as fórmulas):
Se um vetor tem componentes cartesianas (V_x,V_y,V_z) = (1,1,0) no ponto (x,y,z)=(1,1,0), então:
Isso faz sentido: o vetor (1,1,0) aponta radialmente no plano xy, portanto em componentes cilíndricas é puramente radial.
Passo 6
Esboço do algoritmo que o código vai implementar (isto ajuda a escrever o código na prova):
Receber como entrada: componentes do vetor na base de origem e também a posição do ponto (ou os ângulos correspondentes).
Se a posição vier em coordenadas cartesianas, calcular \rho,\varphi,r,\theta usando as fórmulas do Passo 3.
Montar a matriz de transformação apropriada (ver Passo 2) ou aplicar as fórmulas diretas de projeção entre bases.
Aplicar a matriz sobre o vetor de componentes para obter as novas componentes.
Tratar casos singulares com tolerância numérica.
Retornar as componentes no sistema destino e, se desejado, os ângulos usados.
Passo 7
Observações didáticas finais antes do código:
As matrizes que apresentei são ortogonais (colunas são vetores unitários ortonormais), então sua inversa é a transposta — isso simplifica muito a implementação: para ir de A→B pode-se construir as componentes de B como o produto das componentes de A pelos produtos escalares entre as bases.
No tempo de prova, memorizando as expressões das bases (por exemplo \hat{\rho} e \hat{\varphi} em termos de \hat{\imath},\hat{\jmath}) já se consegue montar rapidamente a pequena matriz 2\times2 do plano xy e as linhas/colunas envolvendo \sin\theta,\cos\theta para esférico.
Agora, abaixo está o código final completo que implementa todas as conversões vetoriais entre os três sistemas. Use-o como referência e para testar; ele está comentado e contém funções de utilidade e exemplos de uso.
Resposta
"""
Conversões vetoriais entre sistemas de coordenadas:
- Cartesiano: (x, y, z) com base (i, j, k)
- Cilíndrico: (rho, phi, z) com base (rho_hat, phi_hat, z_hat)
- Esférico : (r, theta, phi) com base (r_hat, theta_hat, phi_hat)
Convenções:
- phi: ângulo azimutal no plano xy, medido a partir do eixo x (atan2(y,x))
- theta: ângulo polar medido a partir do eixo +z (theta = atan2(rho, z))
- Todas as funções esperam/retornam ângulos em radianos.
Funções disponibilizadas:
- cartesian_position_to_spherical(x,y,z) -> (r,theta,phi)
- cartesian_position_to_cylindrical(x,y,z) -> (rho,phi,z)
- cartesian_to_cylindrical_vector(V_cart, x,y,z) -> (V_rho, V_phi, V_z)
- cylindrical_to_cartesian_vector(V_cyl, rho, phi, Vz) -> (Vx, Vy, Vz)
- cartesian_to_spherical_vector(V_cart, x,y,z) -> (V_r, V_theta, V_phi)
- spherical_to_cartesian_vector(V_sph, r, theta, phi) -> (Vx, Vy, Vz)
- cylindrical_to_spherical_vector(V_cyl, rho, phi, z) -> (V_r, V_theta, V_phi)
- spherical_to_cylindrical_vector(V_sph, r, theta, phi) -> (V_rho, V_phi, V_z)
Exemplos de uso no final do arquivo.
"""from math import sqrt, atan2, sin, cos, isclose
EPS = 1e-12defcartesian_position_to_cylindrical(x, y, z):
rho = sqrt(x*x + y*y)
phi = atan2(y, x) ifnot (isclose(x, 0.0, abs_tol=EPS) and isclose(y, 0.0, abs_tol=EPS)) else0.0return rho, phi, z
defcartesian_position_to_spherical(x, y, z):
rho = sqrt(x*x + y*y)
r = sqrt(rho*rho + z*z)
if r < EPS:
# ponto na origem: escolher convenção fixareturn0.0, 0.0, 0.0
phi = atan2(y, x) ifnot isclose(rho, 0.0, abs_tol=EPS) else0.0
theta = atan2(rho, z) # evita dividir por zero; theta in [0, pi]return r, theta, phi
defcartesian_to_cylindrical_vector(V_cart, x, y, z):
"""
V_cart: tuple/list (Vx, Vy, Vz)
position: x, y, z (para obter phi)
retorna: (V_rho, V_phi, V_z)
"""
Vx, Vy, Vz = V_cart
rho, phi, _ = cartesian_position_to_cylindrical(x, y, z)
# phi já está definido mesmo que rho seja zero (convenção = 0)
c = cos(phi); s = sin(phi)
V_rho = c*Vx + s*Vy
V_phi = -s*Vx + c*Vy
return (V_rho, V_phi, Vz)
defcylindrical_to_cartesian_vector(V_cyl, rho, phi, z=None):
"""
V_cyl: tuple/list (V_rho, V_phi, V_z)
rho, phi: posição (phi necessário para orientar as bases)
z: ignorado para a transformação vetorial (mantido por simetria)
retorna: (Vx, Vy, Vz)
"""
V_rho, V_phi, V_z = V_cyl
c = cos(phi); s = sin(phi)
Vx = c*V_rho - s*V_phi
Vy = s*V_rho + c*V_phi
return (Vx, Vy, V_z)
defcartesian_to_spherical_vector(V_cart, x, y, z):
"""
V_cart: (Vx, Vy, Vz)
position: x,y,z (para r,theta,phi)
retorna: (V_r, V_theta, V_phi)
"""
Vx, Vy, Vz = V_cart
r, theta, phi = cartesian_position_to_spherical(x, y, z)
# Se r == 0, ângulos arbitrários; mas as componentes esféricas ficam indefinidas.# Tratamos com convenção: theta=0,phi=0 retornando componentes coerentes.
cphi = cos(phi); sphi = sin(phi)
st = sin(theta); ct = cos(theta)
V_r = st*cphi*Vx + st*sphi*Vy + ct*Vz
V_theta = ct*cphi*Vx + ct*sphi*Vy - st*Vz
V_phi = -sphi*Vx + cphi*Vy
return (V_r, V_theta, V_phi)
defspherical_to_cartesian_vector(V_sph, r, theta, phi):
"""
V_sph: (V_r, V_theta, V_phi)
posição esférica r, theta, phi (apenas theta e phi são necessários para as bases)
retorna: (Vx, Vy, Vz)
"""
V_r, V_theta, V_phi = V_sph
cphi = cos(phi); sphi = sin(phi)
st = sin(theta); ct = cos(theta)
Vx = st*cphi*V_r + ct*cphi*V_theta - sphi*V_phi
Vy = st*sphi*V_r + ct*sphi*V_theta + cphi*V_phi
Vz = ct*V_r - st*V_theta
return (Vx, Vy, Vz)
defcylindrical_to_spherical_vector(V_cyl, rho, phi, z):
"""
V_cyl: (V_rho, V_phi, V_z)
posição: rho, phi, z (para obter theta)
retorna: (V_r, V_theta, V_phi)
"""
V_rho, V_phi, V_z = V_cyl
# calcular theta a partir de rho,zifabs(rho) < EPS andabs(z) < EPS:
theta = 0.0else:
theta = atan2(rho, z)
st = sin(theta); ct = cos(theta)
V_r = st*V_rho + ct*V_z
V_theta = ct*V_rho - st*V_z
V_ph = V_phi
return (V_r, V_theta, V_ph)
defspherical_to_cylindrical_vector(V_sph, r, theta, phi):
"""
V_sph: (V_r, V_theta, V_phi)
posição: r, theta, phi (theta necessário)
retorna: (V_rho, V_phi, V_z)
"""
V_r, V_theta, V_phi = V_sph
st = sin(theta); ct = cos(theta)
V_rho = st*V_r + ct*V_theta
V_z = ct*V_r - st*V_theta
V_ph = V_phi
return (V_rho, V_ph, V_z)
# Exemplos de uso e testes simplesif __name__ == "__main__":
# Exemplo 1: vetor cartesiano no ponto (1,1,0)
V_cart = (1.0, 1.0, 0.0)
x, y, z = 1.0, 1.0, 0.0
V_cyl = cartesian_to_cylindrical_vector(V_cart, x, y, z)
print("Cart -> Cyl:", V_cyl) # espera (sqrt(2), ~0, 0)# Exemplo 2: voltar para cartesiano
rho, phi, _ = cartesian_position_to_cylindrical(x, y, z)
V_cart_back = cylindrical_to_cartesian_vector(V_cyl, rho, phi)
print("Cyl -> Cart:", V_cart_back) # deve recuperar (1,1,0)# Exemplo 3: cartesiano -> esférico (vetorial)
V_sph = cartesian_to_spherical_vector(V_cart, x, y, z)
print("Cart -> Sph:", V_sph)
# Exemplo 4: esférico -> cartesiano (usar r,theta,phi do ponto)
r, theta, phi = cartesian_position_to_spherical(x, y, z)
V_cart_back2 = spherical_to_cartesian_vector(V_sph, r, theta, phi)
print("Sph -> Cart:", V_cart_back2) # deve recuperar aproximado (1,1,0)# Exemplo 5: cilíndrico <-> esférico
V_cyl_example = (1.0, 0.5, -0.2)
rho, phi, z = cartesian_position_to_cylindrical(x, y, z)
V_sph_from_cyl = cylindrical_to_spherical_vector(V_cyl_example, rho, phi, z)
print("Cyl -> Sph:", V_sph_from_cyl)
V_cyl_back = spherical_to_cylindrical_vector(V_sph_from_cyl, *cartesian_position_to_spherical(x,y,z))
print("Sph -> Cyl:", V_cyl_back)