def distance(self, o): """Distance beteen 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 sympy 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 sympy.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 distance(self, o): """Distance beteen 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 sympy 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 sympy.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 arbitrary_point(self, u=None, v=None): """ Returns an arbitrary point on the Plane. If given two parameters, the point ranges over the entire plane. If given 1 or no parameters, returns a point with one parameter which, when varying from 0 to 2*pi, moves the point in a circle of radius 1 about p1 of the Plane. Examples ======== >>> from sympy.geometry import Plane, Ray >>> from sympy.abc import u, v, t, r >>> p = Plane((1, 1, 1), normal_vector=(1, 0, 0)) >>> p.arbitrary_point(u, v) Point3D(1, u + 1, v + 1) >>> p.arbitrary_point(t) Point3D(1, cos(t) + 1, sin(t) + 1) While arbitrary values of u and v can move the point anywhere in the plane, the single-parameter point can be used to construct a ray whose arbitrary point can be located at angle t and radius r from p.p1: >>> Ray(p.p1, _).arbitrary_point(r) Point3D(1, r*cos(t) + 1, r*sin(t) + 1) Returns ======= Point3D """ circle = v is None if circle: u = _symbol(u or 't', real=True) else: u = _symbol(u or 'u', real=True) v = _symbol(v or 'v', real=True) x, y, z = self.normal_vector a, b, c = self.p1.args # x1, y1, z1 is a nonzero vector parallel to the plane if x.is_zero and y.is_zero: x1, y1, z1 = S.One, S.Zero, S.Zero else: x1, y1, z1 = -y, x, S.Zero # x2, y2, z2 is also parallel to the plane, and orthogonal to x1, y1, z1 x2, y2, z2 = tuple(Matrix((x, y, z)).cross(Matrix((x1, y1, z1)))) if circle: x1, y1, z1 = (w / sqrt(x1**2 + y1**2 + z1**2) for w in (x1, y1, z1)) x2, y2, z2 = (w / sqrt(x2**2 + y2**2 + z2**2) for w in (x2, y2, z2)) p = Point3D(a + x1*cos(u) + x2*sin(u), \ b + y1*cos(u) + y2*sin(u), \ c + z1*cos(u) + z2*sin(u)) else: p = Point3D(a + x1 * u + x2 * v, b + y1 * u + y2 * v, c + z1 * u + z2 * v) return p
def arbitrary_point(self, u=None, v=None): """ Returns an arbitrary point on the Plane. If given two parameters, the point ranges over the entire plane. If given 1 or no parameters, returns a point with one parameter which, when varying from 0 to 2*pi, moves the point in a circle of radius 1 about p1 of the Plane. Examples ======== >>> from sympy.geometry import Plane, Ray >>> from sympy.abc import u, v, t, r >>> p = Plane((1, 1, 1), normal_vector=(1, 0, 0)) >>> p.arbitrary_point(u, v) Point3D(1, u + 1, v + 1) >>> p.arbitrary_point(t) Point3D(1, cos(t) + 1, sin(t) + 1) While arbitrary values of u and v can move the point anywhere in the plane, the single-parameter point can be used to construct a ray whose arbitrary point can be located at angle t and radius r from p.p1: >>> Ray(p.p1, _).arbitrary_point(r) Point3D(1, r*cos(t) + 1, r*sin(t) + 1) Returns ======= Point3D """ circle = v is None if circle: u = _symbol(u or 't', real=True) else: u = _symbol(u or 'u', real=True) v = _symbol(v or 'v', real=True) x, y, z = self.normal_vector a, b, c = self.p1.args # x1, y1, z1 is a nonzero vector parallel to the plane if x.is_zero and y.is_zero: x1, y1, z1 = S.One, S.Zero, S.Zero else: x1, y1, z1 = -y, x, S.Zero # x2, y2, z2 is also parallel to the plane, and orthogonal to x1, y1, z1 x2, y2, z2 = tuple(Matrix((x, y, z)).cross(Matrix((x1, y1, z1)))) if circle: x1, y1, z1 = (w/sqrt(x1**2 + y1**2 + z1**2) for w in (x1, y1, z1)) x2, y2, z2 = (w/sqrt(x2**2 + y2**2 + z2**2) for w in (x2, y2, z2)) p = Point3D(a + x1*cos(u) + x2*sin(u), \ b + y1*cos(u) + y2*sin(u), \ c + z1*cos(u) + z2*sin(u)) else: p = Point3D(a + x1*u + x2*v, b + y1*u + y2*v, c + z1*u + z2*v) return p
def random_point(self, seed=None): """ Returns a random point on the Plane. Returns ======= Point3D """ x, y, z = symbols("x, y, z") a = self.equation(x, y, z) from sympy import Rational import random if seed is not None: rng = random.Random(seed) else: rng = random for i in range(10): c = 2*Rational(rng.random()) - 1 s = sqrt(1 - c**2) a = solve(a.subs([(y, c), (z, s)])) if a is []: d = Point3D(0, c, s) else: d = Point3D(a[0], c, s) if d in self: return d raise GeometryError( 'Having problems generating a point in the plane')
def distance(self, o): """ Finds the shortest distance between a line and a point. Raises ====== NotImplementedError is raised if o is not a Point Examples ======== >>> from sympy import Point, Line >>> p1, p2 = Point(0, 0), Point(1, 1) >>> s = Line(p1, p2) >>> s.distance(Point(-1, 1)) sqrt(2) >>> s.distance((-1, 2)) 3*sqrt(2)/2 """ if not isinstance(o, Point): if is_sequence(o): o = Point(o) a, b, c = self.coefficients if 0 in (a, b): return self.perpendicular_segment(o).length m = self.slope x = o.x y = m*x - c/b return abs(factor_terms(o.y - y))/sqrt(1 + m**2)
def distance(self, o): """ Finds the shortest distance between a line and a point. Raises ====== NotImplementedError is raised if o is not a Point Examples ======== >>> from sympy import Point, Line >>> p1, p2 = Point(0, 0), Point(1, 1) >>> s = Line(p1, p2) >>> s.distance(Point(-1, 1)) sqrt(2) """ if not isinstance(o, Point): raise NotImplementedError a, b, c = self.coefficients if 0 in (a, b): return self.perpendicular_segment(o).length m = self.slope x = o.x y = m * x - c / b return abs(factor_terms(o.y - y)) / sqrt(1 + m**2)
def random_point(self, seed=None): """ Returns a random point on the Plane. Returns ======= Point3D """ x, y, z = symbols("x, y, z") a = self.equation(x, y, z) from sympy import Rational import random if seed is not None: rng = random.Random(seed) else: rng = random for i in range(10): c = 2 * Rational(rng.random()) - 1 s = sqrt(1 - c**2) a = solve(a.subs([(y, c), (z, s)])) if a is []: d = Point3D(0, c, s) else: d = Point3D(a[0], c, s) if d in self: return d raise GeometryError('Having problems generating a point in the plane')
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 sympy 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 sympy.geometry.line 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 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 sympy 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 sympy.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 arbitrary_point(self, u=None, v=None): """ Returns an arbitrary point on the Plane. If given two parameters, the point ranges over the entire plane. If given one or no parameters, returns a point with one parameter, varying which from 0 to 2*pi will move the point in a circle of radius 1 about p1 of the Plane. Examples ======== >>> from sympy.geometry.plane import Plane >>> from sympy.abc import u, v, t >>> p = Plane((3, 1, 4), (2, 0, 1), (-1, -2, -2)) >>> p.arbitrary_point(u, v) Point3D(-6*u - 3*v + 3, -3*u + 6*v + 1, 45*v + 4) >>> p.arbitrary_point(t) Point3D(-sqrt(230)*sin(t)/230 - 2*sqrt(5)*cos(t)/5 + 3, sqrt(230)*sin(t)/115 - sqrt(5)*cos(t)/5 + 1, 3*sqrt(230)*sin(t)/46 + 4) Returns ======= Point3D """ circle = v is None u = u or Dummy('u', real=True) v = v or Dummy('v', real=True) x, y, z = self.normal_vector a, b, c = self.p1.args # x1, y1, z1 is a nonzero vector parallel to the plane if x.is_zero and y.is_zero: x1, y1, z1 = S.One, S.Zero, S.Zero else: x1, y1, z1 = -y, x, S.Zero # x2, y2, z2 is also parallel to the plane, and orthogonal to x1, y1, z1 x2, y2, z2 = tuple(Matrix((x, y, z)).cross(Matrix((x1, y1, z1)))) if circle: x1, y1, z1 = (w/sqrt(x1**2 + y1**2 + z1**2) for w in (x1, y1, z1)) x2, y2, z2 = (w/sqrt(x2**2 + y2**2 + z2**2) for w in (x2, y2, z2)) p = Point3D(a + x1*cos(u) + x2*sin(u), \ b + y1*cos(u) + y2*sin(u), \ c + z1*cos(u) + z2*sin(u)) else: p = Point3D(a + x1*u + x2*v, b + y1*u + y2*v, c + z1*u + z2*v) return p
def distance(self, o): """Distance beteen 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 sympy 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 sympy.geometry.line3d import LinearEntity3D x, y, z = symbols("x y z") if self.intersection(o) != []: return S.Zero if isinstance(o, Point3D): k = self.equation(x, y, z) const = [i for i in k.args if i.is_constant() is True] a, b, c = k.coeff(x), k.coeff(y), k.coeff(z) if const != []: d = a*o.x + b*o.y + c*o.z + const.pop() t = sqrt(a**2 + b**2 + c**2) return abs(d / t) else: d = a*o.x + b*o.y + c*o.z t = sqrt(a**2 + b**2 + c**2) return abs(d / 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 _roots(): global _ROOT2, _ROOT3, _invROOT3 _ROOT2, _ROOT3 = sqrt(2), sqrt(3) _invROOT3 = 1 / _ROOT3
def distance(self, o): """Distance beteen 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 sympy 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 sympy.geometry.line3d import LinearEntity3D x, y, z = symbols("x y z") if self.intersection(o) != []: return S.Zero if isinstance(o, Point3D): k = self.equation(x, y, z) const = [i for i in k.args if i.is_constant() is True] a, b, c = k.coeff(x), k.coeff(y), k.coeff(z) if const != []: d = a * o.x + b * o.y + c * o.z + const.pop() t = sqrt(a**2 + b**2 + c**2) return abs(d / t) else: d = a * o.x + b * o.y + c * o.z t = sqrt(a**2 + b**2 + c**2) return abs(d / 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)