def distance(self, o): """Distance between the plane and another geometric entity. Parameters ========== Point3D, LinearEntity3D, Plane. Returns ======= distance Notes ===== This method accepts only 3D entities as it's parameter, but if you want to calculate the distance between a 2D entity and a plane you should first convert to a 3D entity by projecting onto a desired plane and then proceed to calculate the distance. Examples ======== >>> from diofant import Point, Point3D, Line, Line3D, Plane >>> a = Plane(Point3D(1, 1, 1), normal_vector=(1, 1, 1)) >>> b = Point3D(1, 2, 3) >>> a.distance(b) sqrt(3) >>> c = Line3D(Point3D(2, 3, 1), Point3D(1, 2, 2)) >>> a.distance(c) 0 """ from diofant.geometry.line3d import LinearEntity3D x, y, z = map(Dummy, 'xyz') if self.intersection(o) != []: return S.Zero if isinstance(o, Point3D): x, y, z = map(Dummy, 'xyz') k = self.equation(x, y, z) a, b, c = [k.coeff(i) for i in (x, y, z)] d = k.xreplace({x: o.args[0], y: o.args[1], z: o.args[2]}) t = abs(d / sqrt(a**2 + b**2 + c**2)) return t if isinstance(o, LinearEntity3D): a, b = o.p1, self.p1 c = Matrix(a.direction_ratio(b)) d = Matrix(self.normal_vector) e = c.dot(d) f = sqrt(sum(i**2 for i in self.normal_vector)) return abs(e / f) if isinstance(o, Plane): a, b = o.p1, self.p1 c = Matrix(a.direction_ratio(b)) d = Matrix(self.normal_vector) e = c.dot(d) f = sqrt(sum(i**2 for i in self.normal_vector)) return abs(e / f)
def angle_between(self, o): """Angle between the plane and other geometric entity. Parameters ========== LinearEntity3D, Plane. Returns ======= angle : angle in radians Notes ===== This method accepts only 3D entities as it's parameter, but if you want to calculate the angle between a 2D entity and a plane you should first convert to a 3D entity by projecting onto a desired plane and then proceed to calculate the angle. Examples ======== >>> from diofant import Point3D, Line3D, Plane >>> a = Plane(Point3D(1, 2, 2), normal_vector=(1, 2, 3)) >>> b = Line3D(Point3D(1, 3, 4), Point3D(2, 2, 2)) >>> a.angle_between(b) -asin(sqrt(21)/6) """ from diofant.geometry.line3d import LinearEntity3D if isinstance(o, LinearEntity3D): a = Matrix(self.normal_vector) b = Matrix(o.direction_ratio) c = a.dot(b) d = sqrt(sum(i**2 for i in self.normal_vector)) e = sqrt(sum(i**2 for i in o.direction_ratio)) return asin(c / (d * e)) if isinstance(o, Plane): a = Matrix(self.normal_vector) b = Matrix(o.normal_vector) c = a.dot(b) d = sqrt(sum(i**2 for i in self.normal_vector)) e = sqrt(sum(i**2 for i in o.normal_vector)) return acos(c / (d * e))
def is_perpendicular(self, l): """is the given geometric entity perpendicular to the given plane? Parameters ========== LinearEntity3D or Plane Returns ======= Boolean Examples ======== >>> from diofant import Plane, Point3D >>> a = Plane(Point3D(1,4,6), normal_vector=(2, 4, 6)) >>> b = Plane(Point3D(2, 2, 2), normal_vector=(-1, 2, -1)) >>> a.is_perpendicular(b) True """ from diofant.geometry.line3d import LinearEntity3D if isinstance(l, LinearEntity3D): a = Matrix(l.direction_ratio) b = Matrix(self.normal_vector) if a.cross(b).is_zero: return True else: return False elif isinstance(l, Plane): a = Matrix(l.normal_vector) b = Matrix(self.normal_vector) if a.dot(b) == 0: return True else: return False else: return False