def from_three_points(cls, a, b, c): """Construct a plane from three points in three-dimensional space. Parameters ---------- a : [float, float, float] | :class:`compas.geometry.Point` The first point. b : [float, float, float] | :class:`compas.geometry.Point` The second point. c : [float, float, float] | :class:`compas.geometry.Point` The second point. Returns ------- :class:`compas.geometry.Plane` A plane with base point `a` and normal vector defined as the unitized cross product of the vectors `ab` and `ac`. Examples -------- >>> plane = Plane.from_three_points([0.0, 0.0, 0.0], [2.0, 1.0, 0.0], [0.0, 3.0, 0.0]) >>> plane.point Point(0.000, 0.000, 0.000) >>> plane.normal Vector(0.000, 0.000, 1.000) """ a = Point(*a) b = Point(*b) c = Point(*c) normal = Vector.cross(b - a, c - a) return cls(a, normal)
def from_plane(cls, plane): """Constructs a frame from a plane. Xaxis and yaxis are arbitrarily selected based on the plane's normal. Parameters ---------- plane : :class:`compas.geometry.Plane` A plane. Returns ------- :class:`compas.geometry.Frame` The constructed frame. Examples -------- >>> plane = Plane([0,0,0], [0,0,1]) >>> frame = Frame.from_plane(plane) >>> allclose(frame.normal, plane.normal) True """ # plane equation: a*x + b*y + c*z = d d = Vector(*plane.point).dot(plane.normal) # select 2 arbitrary points in the plane from which we create the xaxis coeffs = list(plane.normal) # a, b, c # select a coeff with a value != 0 coeffs_abs = [math.fabs(x) for x in coeffs] idx = coeffs_abs.index(max(coeffs_abs)) # first point coords = [0, 0, 0] # x, y, z # z = (d - a*0 + b*0)/c, if idx == 2 v = d / coeffs[idx] coords[idx] = v pt1_in_plane = Point(*coords) # second point coords = [1, 1, 1] # x, y, z coords[idx] = 0 # z = (d - a*1 + b*1)/c, if idx == 2 v = (d - sum([a * x for a, x in zip(coeffs, coords)])) / coeffs[idx] coords[idx] = v pt2_in_plane = Point(*coords) xaxis = pt2_in_plane - pt1_in_plane yaxis = plane.normal.cross(xaxis) return cls(plane.point, xaxis, yaxis)
def to_local_coords(self, object_in_wcf): """Returns the object's coordinates in the local coordinate system of the frame. Parameters ---------- object_in_wcf : :class:`Point` or :class:`Vector` or :class:`Frame` or list of float An object in the world coordinate frame. Returns ------- :class:`Point` or :class:`Vector` or :class:`Frame` The object in the local coordinate system of the frame. Notes ----- If you pass a list of float, it is assumed to represent a point. Examples -------- >>> from compas.geometry import Point, Frame >>> frame = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) >>> pw = Point(2, 2, 2) # point in wcf >>> pl = frame.to_local_coords(pw) # point in frame >>> frame.to_world_coords(pl) Point(2.000, 2.000, 2.000) """ T = Transformation.change_basis(Frame.worldXY(), self) if isinstance(object_in_wcf, list): return Point(*object_in_wcf).transformed(T) else: return object_in_wcf.transformed(T)
def 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. Examples -------- >>> curve = Bezier([[0.0, 0.0, 0.0], [0.5, 1.0, 0.0], [1.0, 0.0, 0.0]]) >>> curve.point(0.0) Point(0.000, 0.000, 0.000) >>> curve.point(1.0) Point(1.000, 0.000, 0.000) """ 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 points(self, points): self._points = [Point(*xyz) for xyz in points] self._lines = [ Line(self._points[i], self._points[i + 1]) for i in range(0, len(self._points) - 1) ]
def to_world_coordinates(self, object_in_lcf): """Returns the object's coordinates in the global coordinate frame. Parameters ---------- object_in_lcf : :class:`compas.geometry.Point` or :class:`compas.geometry.Vector` or :class:`compas.geometry.Frame` or list of float An object in local coordinate system of the frame. Returns ------- :class:`compas.geometry.Point` or :class:`compas.geometry.Vector` or :class:`compas.geometry.Frame` The object in the world coordinate frame. Notes ----- If you pass a list of float, it is assumed to represent a point. Examples -------- >>> from compas.geometry import Point >>> frame = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) >>> pl = Point(1.632, -0.090, 0.573) # point in frame >>> pw = frame.to_world_coordinates(pl) # point in wcf >>> frame.to_local_coordinates(pw) Point(1.632, -0.090, 0.573) """ T = Transformation.from_change_of_basis(self, Frame.worldXY()) if isinstance(object_in_lcf, list): return Point(*object_in_lcf).transformed(T) else: return object_in_lcf.transformed(T)
def local_to_local_coordinates(frame1, frame2, object_in_frame1): """Returns the object's coordinates in frame1 in the local coordinates of frame2. Parameters ---------- frame1 : :class:`compas.geometry.Frame` A frame representing one local coordinate system. frame2 : :class:`compas.geometry.Frame` A frame representing another local coordinate system. object_in_frame1 : :class:`compas.geometry.Point` or :class:`compas.geometry.Vector` or :class:`compas.geometry.Frame` or list of float An object in the coordinate frame1. If you pass a list of float, it is assumed to represent a point. Returns ------- :class:`compas.geometry.Point` or :class:`compas.geometry.Vector` or :class:`compas.geometry.Frame` The object in the local coordinate system of frame2. Examples -------- >>> from compas.geometry import Point >>> frame1 = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) >>> frame2 = Frame([2, 1, 3], [1., 0., 0.], [0., 1., 0.]) >>> p1 = Point(2, 2, 2) # point in frame1 >>> p2 = Frame.local_to_local_coordinates(frame1, frame2, p1) # point in frame2 >>> Frame.local_to_local_coordinates(frame2, frame1, p2) Point(2.000, 2.000, 2.000) """ T = Transformation.from_change_of_basis(frame1, frame2) if isinstance(object_in_frame1, list): return Point(*object_in_frame1).transformed(T) return object_in_frame1.transformed(T)
def represent_point_in_global_coordinates(self, point): """Represents a point from local coordinates in the world coordinate system. Parameters ---------- point : :obj:`list` of :obj:`float` or :class:`Point` A point in local coordinates. Returns ------- :class:`Point` A point in the world coordinate system. Examples -------- >>> from compas.geometry import Frame >>> f = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) >>> pw1 = [2, 2, 2] >>> pf = f.represent_point_in_local_coordinates(pw1) >>> pw2 = f.represent_point_in_global_coordinates(pf) >>> allclose(pw1, pw2) True """ T = matrix_from_frame(self) pt = Point(*point) pt.transform(T) return pt
def represent_point_in_local_coordinates(self, point): """Represents a point in the frame's local coordinate system. Parameters ---------- point : :obj:`list` of :obj:`float` or :class:`Point` A point in world XY. Returns ------- :class:`Point` A point in the local coordinate system of the frame. Examples -------- >>> from compas.geometry import Frame >>> f = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) >>> pw1 = [2, 2, 2] >>> pf = f.represent_point_in_local_coordinates(pw1) >>> pw2 = f.represent_point_in_global_coordinates(pf) >>> allclose(pw1, pw2) True """ pt = Point(*subtract_vectors(point, self.point)) T = inverse(matrix_from_basis_vectors(self.xaxis, self.yaxis)) pt.transform(T) return pt
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_three_points(cls, a, b, c): """Construct a plane from three points in three-dimensional space. Parameters ---------- a : point The first point. b : point The second point. c : point The second point. Returns ------- Plane A plane with base point ``a`` and normal vector defined as the unitized cross product of the vectors ``ab`` and ``ac``. """ a = Point(*a) b = Point(*b) c = Point(*c) normal = Vector.cross(b - a, c - a) return cls(a, normal)
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 __setitem__(self, key, value): self.points[key] = Point(*value) self._lines = None
def centroid(self): """int : The centroid of the polygon.""" point = centroid_polygon(self.points) return Point(*point)
def points(self, points): if points[-1] == points[0]: del points[-1] self._points = [Point(*xyz) for xyz in points] self._lines = None
def end(self, point): self._end = Point(*point)
def start(self, point): self._start = Point(*point)
def point(self, point): self._point = Point(*point)
def centroid(self): point = centroid_polygon(self.points) return Point(*point)
def centroid(self): """int: The centroid of the polygon.""" return Point(*centroid_points(self.points))
def center(self): """Point: The center (of mass) of the polygon.""" return Point(*centroid_polygon(self.points))
def points(self, points): if points: self._points = [Point(*point) for point in points]
>>> from compas.geometry import Transformation >>> from compas.geometry import Sphere >>> sphere = Sphere(Point(1, 1, 1), 5) >>> frame = Frame([1, 1, 1], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) >>> T = Transformation.from_frame(frame) >>> sphere_transformed = sphere.transformed(T) """ sphere = self.copy() sphere.transform(transformation) return sphere if __name__ == '__main__': from compas.geometry import Frame from compas.geometry import Transformation sphere = Sphere(Point(1, 1, 1), 5) frame = Frame([5, 0, 0], [0.68, 0.68, 0.27], [-0.67, 0.73, -0.15]) T = Transformation.from_frame(frame) sphere.transform(T) print(sphere) sphere = Sphere(Point(1, 1, 1), 5) print(sphere.data) print(sphere) sphere = Sphere.from_data(sphere.data) print(sphere) import doctest doctest.testmod()
def points(self, points): self._points = [Point(*xyz) for xyz in points] self._lines = None
""" plane = self.copy() plane.transform(transformation) return plane # ============================================================================== # Main # ============================================================================== if __name__ == '__main__': from compas.geometry import Frame from compas.geometry import Transformation base = Point(0.0, 0.0, 0.0) normal = Vector(1.0, 0.0, 0.0) plane = Plane(base, normal) print(plane) print(plane.d) a, b, c = normal p = [1.0, 0.0, 1.0] d = a * p[0] + b * p[1] + c * p[2] print(d) print(d <= plane.d)