123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- from sympy.core.basic import Basic
- from sympy.core.symbol import Str
- from sympy.vector.vector import Vector
- from sympy.vector.coordsysrect import CoordSys3D
- from sympy.vector.functions import _path
- from sympy.core.cache import cacheit
- class Point(Basic):
- """
- Represents a point in 3-D space.
- """
- def __new__(cls, name, position=Vector.zero, parent_point=None):
- name = str(name)
- # Check the args first
- if not isinstance(position, Vector):
- raise TypeError(
- "position should be an instance of Vector, not %s" % type(
- position))
- if (not isinstance(parent_point, Point) and
- parent_point is not None):
- raise TypeError(
- "parent_point should be an instance of Point, not %s" % type(
- parent_point))
- # Super class construction
- if parent_point is None:
- obj = super().__new__(cls, Str(name), position)
- else:
- obj = super().__new__(cls, Str(name), position, parent_point)
- # Decide the object parameters
- obj._name = name
- obj._pos = position
- if parent_point is None:
- obj._parent = None
- obj._root = obj
- else:
- obj._parent = parent_point
- obj._root = parent_point._root
- # Return object
- return obj
- @cacheit
- def position_wrt(self, other):
- """
- Returns the position vector of this Point with respect to
- another Point/CoordSys3D.
- Parameters
- ==========
- other : Point/CoordSys3D
- If other is a Point, the position of this Point wrt it is
- returned. If its an instance of CoordSyRect, the position
- wrt its origin is returned.
- Examples
- ========
- >>> from sympy.vector import CoordSys3D
- >>> N = CoordSys3D('N')
- >>> p1 = N.origin.locate_new('p1', 10 * N.i)
- >>> N.origin.position_wrt(p1)
- (-10)*N.i
- """
- if (not isinstance(other, Point) and
- not isinstance(other, CoordSys3D)):
- raise TypeError(str(other) +
- "is not a Point or CoordSys3D")
- if isinstance(other, CoordSys3D):
- other = other.origin
- # Handle special cases
- if other == self:
- return Vector.zero
- elif other == self._parent:
- return self._pos
- elif other._parent == self:
- return -1 * other._pos
- # Else, use point tree to calculate position
- rootindex, path = _path(self, other)
- result = Vector.zero
- i = -1
- for i in range(rootindex):
- result += path[i]._pos
- i += 2
- while i < len(path):
- result -= path[i]._pos
- i += 1
- return result
- def locate_new(self, name, position):
- """
- Returns a new Point located at the given position wrt this
- Point.
- Thus, the position vector of the new Point wrt this one will
- be equal to the given 'position' parameter.
- Parameters
- ==========
- name : str
- Name of the new point
- position : Vector
- The position vector of the new Point wrt this one
- Examples
- ========
- >>> from sympy.vector import CoordSys3D
- >>> N = CoordSys3D('N')
- >>> p1 = N.origin.locate_new('p1', 10 * N.i)
- >>> p1.position_wrt(N.origin)
- 10*N.i
- """
- return Point(name, position, self)
- def express_coordinates(self, coordinate_system):
- """
- Returns the Cartesian/rectangular coordinates of this point
- wrt the origin of the given CoordSys3D instance.
- Parameters
- ==========
- coordinate_system : CoordSys3D
- The coordinate system to express the coordinates of this
- Point in.
- Examples
- ========
- >>> from sympy.vector import CoordSys3D
- >>> N = CoordSys3D('N')
- >>> p1 = N.origin.locate_new('p1', 10 * N.i)
- >>> p2 = p1.locate_new('p2', 5 * N.j)
- >>> p2.express_coordinates(N)
- (10, 5, 0)
- """
- # Determine the position vector
- pos_vect = self.position_wrt(coordinate_system.origin)
- # Express it in the given coordinate system
- return tuple(pos_vect.to_matrix(coordinate_system))
- def _sympystr(self, printer):
- return self._name
|