def __setitem__(self, key, value): if key == 0: self.start = Point(value) return if key == 1: self.end = Point(value) return raise KeyError
def from_three_points(cls, p1, p2, p3): p1 = Point(p1) p2 = Point(p2) p3 = Point(p3) v1 = p2 - p1 v2 = p3 - p1 plane = cls() plane.point = p1 plane.normal = v1.cross(v2) return plane
def from_points_and_vector(cls, p1, p2, vector): p1 = Point(p1) p2 = Point(p2) v1 = p2 - p1 n = v1.cross(vector) n.normalize() plane = cls() plane.point = p1 plane.normal = n return plane
def points(self, points): if points[-1] == points[0]: del points[-1] self.points = [Point(xyz) for xyz in points] self.lines = [ Line(self.points[i], self.points[i + 1]) for i in range(-1, len(points) - 1) ]
def from_point_and_vectors(cls, point, v1, v2): v1 = Vector(v1) v2 = Vector(v2) n = v1.cross(v2) n.normalize() plane = cls() plane.point = Point(point) plane.normal = n return plane
def compute_point(self, t): """Compute a point on the curve. Parameters: t (float): The value of the curve parameter. Must be between 0 and 1. Returns: Point: the corresponding point on the curve. """ n = self.degree point = Point([0, 0, 0]) for i, p in enumerate(self.points): b = bernstein(n, i, t) point += p * b return point
def centroid(self): """The centroid of the polygon.""" return Point(centroid_points(self.points))
def center(self): """The center (of mass) of the polygon.""" return Point(center_of_mass_polygon(self.points))
def __init__(self, p1, p2): self.start = Point(p1) self.end = Point(p2)
def rotate(self, angle, origin=None): """Rotate the line around the origin, or around a specified origin.""" if not origin: origin = [0, 0, 0] origin = Point(origin)
class Line(object): r"""A ``Line`` object is defined by two points in three-dimensional space. Parameters: p1 (tuple, list, Point): The xyz coordinates of the first point. p2 (tuple, list, Point): The xyz coordinates of the second point. Attributes: start (Point): The start point. end (Point): The end point. length (float): (**read-only**) The length of the line between start and end. midpoint (Point): (**read-only**) The midpoint between start and end. direction (Vector): (**read-only**) A unit vector pointing from start to end. Note: For convenience, this class implements the following *magic* methods: * ``__repr__`` * ``__len__`` * ``__getitem__`` * ``__setitem__`` * ``__iter__`` * ``__mul__`` * ``__imul__`` Examples: >>> line = Line([0,0,0], [1,1,1]) >>> line.midpoint [0.5, 0.5, 0.0] >>> line.length 1.73205080757 >>> line.direction [0.57735026919, 0.57735026919, 0.57735026919] >>> type(line.start) <class 'point.Point'> >>> type(line.midpoint) <class 'point.Point'> >>> type(line.direction) <class 'vector.Vector'> References: https://en.wikipedia.org/wiki/Linear_equation """ def __init__(self, p1, p2): self.start = Point(p1) self.end = Point(p2) def __repr__(self): return '({0}, {1})'.format(self.start, self.end) def __len__(self): return 2 def __getitem__(self, key): if key == 0: return self.start if key == 1: return self.end raise KeyError def __setitem__(self, key, value): if key == 0: self.start = Point(value) return if key == 1: self.end = Point(value) return raise KeyError def __iter__(self): return iter([self.start, self.end]) def __mul__(self, n): """Create a line with the same start point and direction, but scaled length. Parameters: n (int, float): The scaling factor. Returns: Line: A line with the same start point and direction, but scaled length. """ v = self.direction * (n * self.length) return Line(self.start, self.start + v) def __imul__(self, n): v = self.direction * (n * self.length) self.end = self.start + v return self # -------------------------------------------------------------------------- # descriptors # -------------------------------------------------------------------------- @property def vector(self): """A vector pointing from start to end. Returns: Vector: The vector. """ return self.end - self.start @property def length(self): """The length of the vector from start to end. Returns: float: The length. """ return self.vector.length @property def midpoint(self): """The midpoint between start and end. Returns: Point: The midpoint. """ v = self.direction * (0.5 * self.length) return self.start + v @property def direction(self): """A unit vector pointing from start and end. Returns: Vector: The direction. """ return self.vector * (1 / self.length) # -------------------------------------------------------------------------- # transformations # -------------------------------------------------------------------------- def translate(self, vector): """Translate the line by a vector.""" self.start.translate(vector) self.end.translate(vector) def rotate(self, angle, origin=None): """Rotate the line around the origin, or around a specified origin.""" if not origin: origin = [0, 0, 0] origin = Point(origin) def scale(self, n): """Increase the distance between start and end by a factor n, while keeping the start point fixed. Parameters: n (int, float): The scaling factor. Note: This is an alias for self \*= n """ self *= n
def points(self, points): if points: self.points = [Point(point) for point in points]
def points(self, points): self.points = [Point(xyz) for xyz in points] self.p = len(points) self.lines = [Line(self.points[i], self.points[i + 1]) for i in range(0, self.p - 1)] self.l = len(self.lines)
def from_point_and_normal(cls, point, normal): plane = cls() plane.point = Point(point) plane.normal = Vector(normal).normalize() return plane