point.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. from sympy.core.basic import Basic
  2. from sympy.core.symbol import Str
  3. from sympy.vector.vector import Vector
  4. from sympy.vector.coordsysrect import CoordSys3D
  5. from sympy.vector.functions import _path
  6. from sympy.core.cache import cacheit
  7. class Point(Basic):
  8. """
  9. Represents a point in 3-D space.
  10. """
  11. def __new__(cls, name, position=Vector.zero, parent_point=None):
  12. name = str(name)
  13. # Check the args first
  14. if not isinstance(position, Vector):
  15. raise TypeError(
  16. "position should be an instance of Vector, not %s" % type(
  17. position))
  18. if (not isinstance(parent_point, Point) and
  19. parent_point is not None):
  20. raise TypeError(
  21. "parent_point should be an instance of Point, not %s" % type(
  22. parent_point))
  23. # Super class construction
  24. if parent_point is None:
  25. obj = super().__new__(cls, Str(name), position)
  26. else:
  27. obj = super().__new__(cls, Str(name), position, parent_point)
  28. # Decide the object parameters
  29. obj._name = name
  30. obj._pos = position
  31. if parent_point is None:
  32. obj._parent = None
  33. obj._root = obj
  34. else:
  35. obj._parent = parent_point
  36. obj._root = parent_point._root
  37. # Return object
  38. return obj
  39. @cacheit
  40. def position_wrt(self, other):
  41. """
  42. Returns the position vector of this Point with respect to
  43. another Point/CoordSys3D.
  44. Parameters
  45. ==========
  46. other : Point/CoordSys3D
  47. If other is a Point, the position of this Point wrt it is
  48. returned. If its an instance of CoordSyRect, the position
  49. wrt its origin is returned.
  50. Examples
  51. ========
  52. >>> from sympy.vector import CoordSys3D
  53. >>> N = CoordSys3D('N')
  54. >>> p1 = N.origin.locate_new('p1', 10 * N.i)
  55. >>> N.origin.position_wrt(p1)
  56. (-10)*N.i
  57. """
  58. if (not isinstance(other, Point) and
  59. not isinstance(other, CoordSys3D)):
  60. raise TypeError(str(other) +
  61. "is not a Point or CoordSys3D")
  62. if isinstance(other, CoordSys3D):
  63. other = other.origin
  64. # Handle special cases
  65. if other == self:
  66. return Vector.zero
  67. elif other == self._parent:
  68. return self._pos
  69. elif other._parent == self:
  70. return -1 * other._pos
  71. # Else, use point tree to calculate position
  72. rootindex, path = _path(self, other)
  73. result = Vector.zero
  74. i = -1
  75. for i in range(rootindex):
  76. result += path[i]._pos
  77. i += 2
  78. while i < len(path):
  79. result -= path[i]._pos
  80. i += 1
  81. return result
  82. def locate_new(self, name, position):
  83. """
  84. Returns a new Point located at the given position wrt this
  85. Point.
  86. Thus, the position vector of the new Point wrt this one will
  87. be equal to the given 'position' parameter.
  88. Parameters
  89. ==========
  90. name : str
  91. Name of the new point
  92. position : Vector
  93. The position vector of the new Point wrt this one
  94. Examples
  95. ========
  96. >>> from sympy.vector import CoordSys3D
  97. >>> N = CoordSys3D('N')
  98. >>> p1 = N.origin.locate_new('p1', 10 * N.i)
  99. >>> p1.position_wrt(N.origin)
  100. 10*N.i
  101. """
  102. return Point(name, position, self)
  103. def express_coordinates(self, coordinate_system):
  104. """
  105. Returns the Cartesian/rectangular coordinates of this point
  106. wrt the origin of the given CoordSys3D instance.
  107. Parameters
  108. ==========
  109. coordinate_system : CoordSys3D
  110. The coordinate system to express the coordinates of this
  111. Point in.
  112. Examples
  113. ========
  114. >>> from sympy.vector import CoordSys3D
  115. >>> N = CoordSys3D('N')
  116. >>> p1 = N.origin.locate_new('p1', 10 * N.i)
  117. >>> p2 = p1.locate_new('p2', 5 * N.j)
  118. >>> p2.express_coordinates(N)
  119. (10, 5, 0)
  120. """
  121. # Determine the position vector
  122. pos_vect = self.position_wrt(coordinate_system.origin)
  123. # Express it in the given coordinate system
  124. return tuple(pos_vect.to_matrix(coordinate_system))
  125. def _sympystr(self, printer):
  126. return self._name