Spaces:
Sleeping
Sleeping
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 | |
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 | |