index ce055a4..9a5fa8f 100644 (file)
@@ -1,3 +1,20 @@
+#
+# This file is part of Linpy.
+#
+# Linpy is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Linpy is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linpy.  If not, see <http://www.gnu.org/licenses/>.
+
import math
import numbers
import operator
@@ -71,6 +88,9 @@ class Coordinates:

__getitem__ = coordinate

+    def values(self):
+        yield from self._coordinates.values()
+
def __bool__(self):
return any(self._coordinates.values())

@@ -104,15 +124,27 @@ class Point(Coordinates, GeometricObject):
"""

def isorigin(self):
+        """
+        Return True if a Point is the origin.
+        """
return not bool(self)

+    def __hash__(self):
+        return super().__hash__()
+
+        """
+        Adds a Point to a Vector and returns the result as a Point.
+        """
if not isinstance(other, Vector):
return NotImplemented
return Point(coordinates)

def __sub__(self, other):
+        """
+        Returns the difference between two Points as a Vector.
+        """
coordinates = []
if isinstance(other, Point):
coordinates = self._map2(other, operator.sub)
@@ -124,10 +156,16 @@ class Point(Coordinates, GeometricObject):
return NotImplemented

def __eq__(self, other):
+        """
+        Compares two Points for equality.
+        """
return isinstance(other, Point) and \
self._coordinates == other._coordinates

def aspolyhedron(self):
+        """
+        Return a Point as a polyhedron.
+        """
from .polyhedra import Polyhedron
equalities = []
for symbol, coordinate in self.coordinates():
@@ -145,15 +183,25 @@ class Vector(Coordinates):
initial = Point(initial)
if terminal is None:
coordinates = initial._coordinates
-        elif not isinstance(terminal, Point):
-            terminal = Point(terminal)
+        else:
+            if not isinstance(terminal, Point):
+                terminal = Point(terminal)
coordinates = terminal._map2(initial, operator.sub)
return super().__new__(cls, coordinates)

def isnull(self):
+        """
+        Returns true if a Vector is null.
+        """
return not bool(self)

+    def __hash__(self):
+        return super().__hash__()
+
+        """
+        Adds either a Point or Vector to a Vector.
+        """
if isinstance(other, (Point, Vector)):
return other.__class__(coordinates)
@@ -209,6 +257,9 @@ class Vector(Coordinates):
return result

def __eq__(self, other):
+        """
+        Compares two Vectors for equality.
+        """
return isinstance(other, Vector) and \
self._coordinates == other._coordinates

@@ -216,6 +267,9 @@ class Vector(Coordinates):
return hash(tuple(self.coordinates()))

def __mul__(self, other):
+        """
+        Multiplies a Vector by a scalar value.
+        """
if not isinstance(other, numbers.Real):
return NotImplemented
coordinates = self._map(lambda coordinate: other * coordinate)
@@ -224,10 +278,16 @@ class Vector(Coordinates):
__rmul__ = __mul__

def __neg__(self):
+        """
+        Returns the negated form of a Vector.
+        """
coordinates = self._map(operator.neg)
return Vector(coordinates)

def norm(self):
+        """
+        Normalizes a Vector.
+        """
return math.sqrt(self.norm2())

def norm2(self):
@@ -240,6 +300,9 @@ class Vector(Coordinates):
return self / self.norm()

def __sub__(self, other):
+        """
+        Subtract a Point or Vector from a Vector.
+        """
if isinstance(other, (Point, Vector)):
coordinates = self._map2(other, operator.sub)
return other.__class__(coordinates)