Clase que representa coordenadas cartesianas y esféricas -- python campo con classes campo con coordinate-system camp codereview Relacionados El problema

Class representing both cartesian and spherical coordinates


6
vote

problema

Español

He tenido poca experiencia con la programación OO, siendo un ingeniero típico. Tiendo a hackear un código funcional. Sin embargo, estoy tratando de cambiar eso y veo valor en la implementación de OO al modelar el mundo físico. He escrito mi primera clase para una vector de posición . Quiero una instancia de la clase para poder almacenar tanto el 998877666555443344 9988777655554433555544335 coordenadas de una posición. Actualizar un atributo actualiza automáticamente a los demás. Esta clase se reutilizará más tarde en otras clases a través de la composición.

Quiero una instancia de mi clase para hacer lo siguiente:

  >> p = PositionVector([15,5,5]) >> p.cartesian [15,5,5] >> p.polar [16.583123951777, 0.0, 1.2645189576252271] >> p.x = 3 >> p.cartesian [3,5,5] >> p.polar [7.681145747868608, 0.7853981633974483, 0.8619682853367363] >> p.theta = 0.5 >> p.cartesian [5.117141702137862, 2.7955072527614058, 5.0] >> p.polar [7.681145747868608, 0.5, 0.8619682853367363]   

La clase que he escrito hasta ahora está abajo y, mientras funciona como se esperaba, mi entendimiento limitado de las clases de Python y la función de la propiedad me dice que es una mejor manera de hacer esto. No sé si los métodos para xyzr theta y phi deben estar completamente escritos, ya que son elementos simplemente dentro de cada lista / matriz, pero no se pueden descubrir cómo diviértete esto. Tampoco sé si esta es la forma más segura y más pitónica de estructurar un objeto de clase:

  class PositionVector(object):   def __init__(self, vector, system='cartesian'):     if system == 'cartesian':       self.cartesian = vector       self.polar = self.position_vector_polar(self.cartesian)     if system == 'polar':       self.polar = vector       self.cartesian = self.position_vector_cartesian(self.polar)    @property   def cartesian(self):     return self._cartesian   @cartesian.setter   def cartesian(self, value):     self._cartesian = value     self._polar = self.position_vector_polar(self._cartesian)     self._x, self._y, self._z = self._cartesian     self._r, self._theta, self._phi = self._polar    @property   def polar(self):     return self._polar   @polar.setter   def polar(self, value):     self._polar = value     self._cartesian  = self.position_vector_cartesian(self._polar)     self._x, self._y, self._z = self.cartesian     self._r, self._theta, self._phi = self.polar    @property   def x(self):     return self._x   @x.setter   def x(self, value):     self._x = value     self._cartesian[0]  = self._x     self._polar = self.position_vector_polar(self._cartesian)    # repeat above for y and z variables    @property   def r(self):     return self._r   @r.setter   def r(self, value):     self._r = value     self._polar[0]  = self._r     self._cartesian = self.position_vector_cartesian(self._polar)    # repeat above for thets and phi variables    def position_vector_cartesian(self, polar):     r, theta, phi = polar     x = r * math.cos(theta) * math.sin(phi)     y = r * math.sin(theta) * math.sin(phi)     z = r * math.cos(phi)     return [x, y, z]    def position_vector_polar(self, cartesian):     x, y, z = cartesian     r = math.sqrt(x ** 2 + y ** 2 + z ** 2)     theta = math.atan(y/x)     phi = math.acos(z/r)     return [r, theta, phi]   

Tenga en cuenta que las listas se reemplazarán con arreglos numeros para poder realizar álgebra en los vectores, pero por ahora solo quiero obtener la estructura de la clase correcta.

Original en ingles

I have had little experience with OO programming, being a typical engineer I tend to hack together functional code. However, I'm trying to change that and I see value in implementing OO when modelling the physical world. I've written my first ever class for a position vector. I want an instance of the class to be able to store both the cartesian [x, y, z] and polar [z, theta, phi] coordinates of a position. Updating one attribute automatically updates the others. This class will be later be reused in other classes via composition.

I want an instance of my class to do the following:

>> p = PositionVector([15,5,5]) >> p.cartesian [15,5,5] >> p.polar [16.583123951777, 0.0, 1.2645189576252271] >> p.x = 3 >> p.cartesian [3,5,5] >> p.polar [7.681145747868608, 0.7853981633974483, 0.8619682853367363] >> p.theta = 0.5 >> p.cartesian [5.117141702137862, 2.7955072527614058, 5.0] >> p.polar [7.681145747868608, 0.5, 0.8619682853367363] 

The class I've written so far is below and while it works as expected, my limited understanding of Python classes and the property function tells me there's a better way to do this. I don't know if the methods for x y z r theta and phi need to be fully written since they are simply elements within each list/array but can't figure out how to get around this. I also don't know if this is the safest and most pythonic way of structuring a class object:

class PositionVector(object):   def __init__(self, vector, system='cartesian'):     if system == 'cartesian':       self.cartesian = vector       self.polar = self.position_vector_polar(self.cartesian)     if system == 'polar':       self.polar = vector       self.cartesian = self.position_vector_cartesian(self.polar)    @property   def cartesian(self):     return self._cartesian   @cartesian.setter   def cartesian(self, value):     self._cartesian = value     self._polar = self.position_vector_polar(self._cartesian)     self._x, self._y, self._z = self._cartesian     self._r, self._theta, self._phi = self._polar    @property   def polar(self):     return self._polar   @polar.setter   def polar(self, value):     self._polar = value     self._cartesian  = self.position_vector_cartesian(self._polar)     self._x, self._y, self._z = self.cartesian     self._r, self._theta, self._phi = self.polar    @property   def x(self):     return self._x   @x.setter   def x(self, value):     self._x = value     self._cartesian[0]  = self._x     self._polar = self.position_vector_polar(self._cartesian)    # repeat above for y and z variables    @property   def r(self):     return self._r   @r.setter   def r(self, value):     self._r = value     self._polar[0]  = self._r     self._cartesian = self.position_vector_cartesian(self._polar)    # repeat above for thets and phi variables    def position_vector_cartesian(self, polar):     r, theta, phi = polar     x = r * math.cos(theta) * math.sin(phi)     y = r * math.sin(theta) * math.sin(phi)     z = r * math.cos(phi)     return [x, y, z]    def position_vector_polar(self, cartesian):     x, y, z = cartesian     r = math.sqrt(x ** 2 + y ** 2 + z ** 2)     theta = math.atan(y/x)     phi = math.acos(z/r)     return [r, theta, phi] 

Note that the lists will be be replaced with NumPy arrays so I can perform algebra on the vectors, but for now I just want to get the class structure correct.

        

Lista de respuestas

3
 
vote

En la medida en que entiendo el código, un objeto 99887776655544330 tiene coordenadas cartesianas y polares. Esto es seguramente redundante: las representaciones múltiples de la misma posición no tienen más información que una sola (tenga en cuenta que hay muchos más sistemas de coordenadas, y no puede tener en cuenta todos ellos). Recomiendo mantener la posición en un sistema de coordenadas preferido y proporcionar métodos para convertirla hacia y desde otras representaciones.

Editar : Destacan las preocupaciones en el comentario:

¿Qué tal si quiero establecer un nuevo radio, R? Lo que más sería manera apropiada de actualizar [x, y, z]?

Esta es una pregunta muy importante que no había elaborado en la respuesta. En el mundo algebraico, queremos razonar en términos de objetos, a diferencia de las coordenadas. Las coordenadas son secundarias: son solo instrumentales para los cálculos.

En otras palabras, no desea establecer un nuevo radio. Desea aplicar una transformación (traducir, rotar, escala, etc.).

Escribí la clase con el Posibilidad de aplicar en mente vector álgebra, si sigo su sugerencia, El álgebra vectorial será directo, independientemente de lo que Ordenadas con el que estoy trabajando?

Espero seriamente también.

 

As far as I understand the code, a PositionVector object holds both cartesian and polar coordinates. This is surely redundant: multiple representations of the same position hold no more information than a single one (note that there are many more coordinate systems, and you cannot possibly account for all of them). I recommend to keep the position in a preferred coordinate system, and provide methods to convert it to and from other representations.

Edit: addressing concerns in the comment:

What about if I want to set a new radius, r? What would be the most appropriate way to update [x, y, z]?

This is a very important question I didn't elaborate on in the answer. In the algebraic world we want to reason in terms of objects, as opposed to coordinates. Coordinates are secondary - they are just instrumental for calculations.

In other words, you do not want to set new radius. You want to apply a transformation (translate, rotate, scale, etc).

I wrote the class with the ability to apply vector algebra in mind, if I follow your suggestion, would vector algebra be straight forward, regardless of which ordinates I am working with?

I seriously hope so.

 
 
     
     

Relacionados problema

21  Conversión de coordenadas polares a coordenadas rectangulares  ( Converting from polar coordinates to rectangular coordinates ) 
Este es un rendimiento crítico. Medí y determiné que el uso de 99887766655443319 es más rápido que usar el método 99887766655443320 . Soy consciente de q...

5  Clase de vectores matemáticas fuertemente planteladas  ( Heavily templated mathematical vector class ) 
Comencé a escribir una biblioteca para el álgebra lineal para uso personal, pero también para la revitilización de mi C ++. A continuación se muestra la pri...

4  Implementación de Quadtree C ++  ( Quadtree c implementation ) 
Recientemente creé una implementación de Quadtree en C ++. Varía ligeramente de la mayoría de las implementaciones. En lugar de almacenar elementos, solo or...

3  Clases NODE2D y NODE3D implementadas utilizando un decorador compartido  ( Node2d and node3d classes implemented using a shared decorator ) 
Editar: He hecho otro Ir a esto usando Metaclasses aquí . Creo que es un enfoque mucho mejor. Tengo las siguientes clases. validator es un decorador que ...

14  Comparación con el infinito al verificar si un punto está por encima de una línea  ( Comparison to infinity when checking if a point is above a line ) 
Tengo una función que se llama en un bucle apretado. He perfilado mi código y aquí es donde está mi cuello de botella más grande. La función es bastante simpl...

5  Fórmula Haversine en Clojure  ( Haversine formula in clojure ) 
Implementé el fórmula haversine para calcular la distancia entre dos (latitud , longitud) coordenadas. Me preguntaba si se ve natural para los programador...

1  Calculadora de vector simple [cerrado]  ( Simple vector calculator ) 
cerrado . Esta pregunta necesita detalles o claridad . Actualmente no está aceptando respuestas. ...

10  Encuentra el hogar visible no visible más cercano  ( Find the closest unvisited visible home ) 
Estoy escribiendo un juego más alto de 2D donde realizo una gran cantidad de búsquedas "más cercanas" entre un punto y todo el resto de los puntos. En este ...

1  Funciones de comparación para 2D puntos [cerrados]  ( Comparison functions for 2d points ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

17  Implementación vectorial (física)  ( Vector physics implementation ) 
Recientemente comencé a aprender Java, y decidí implementar un sistema de vectores básico para otro sistema de partículas que estaba construyendo. join()9 ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos