def test_parameter_value(): t = Symbol('t') sq = Polygon((0, 0), (0, 1), (1, 1), (1, 0)) assert sq.parameter_value((0.5, 1), t) == {t: S(3)/8} q = Polygon((0, 0), (2, 1), (2, 4), (4, 0)) assert q.parameter_value((4, 0), t) == {t: -6 + 3*sqrt(5)} # ~= 0.708 raises(ValueError, lambda: sq.parameter_value((5, 6), t))
def test_encloses(): # square with a dimpled left side s = Polygon(Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1), Point(S.Half, S.Half)) # the following will be True if the polygon isn't treated as closing on itself assert s.encloses(Point(0, S.Half)) is False assert s.encloses(Point(S.Half, S.Half)) is False # it's a vertex assert s.encloses(Point(Rational(3, 4), S.Half)) is True
def test_issue_12966(): poly = Polygon(Point(0, 0), Point(0, 10), Point(5, 10), Point(5, 5), Point(10, 5), Point(10, 0)) t = Symbol('t') pt = poly.arbitrary_point(t) DELTA = 5/poly.perimeter assert [pt.subs(t, DELTA*i) for i in range(int(1/DELTA))] == [ Point(0, 0), Point(0, 5), Point(0, 10), Point(5, 10), Point(5, 5), Point(10, 5), Point(10, 0), Point(5, 0)]
def test_util_centroid(): p = Polygon((0, 0), (10, 0), (10, 10)) q = p.translate(0, 20) assert centroid(p, q) == Point(20, 40) / 3 p = Segment((0, 0), (2, 0)) q = Segment((0, 0), (2, 2)) assert centroid(p, q) == Point(1, 2 * sqrt(2) / (2 + 2 * sqrt(2))) assert centroid(Point(0, 0), Point(2, 0)) == Point(2, 0) / 2 assert centroid(Point(0, 0), Point(0, 0), Point(2, 0)) == Point(2, 0) / 3
def test_intersection(): poly1 = Triangle(Point(0, 0), Point(1, 0), Point(0, 1)) poly2 = Polygon(Point(0, 1), Point(-5, 0), Point(0, -4), Point(0, S(1)/5), Point(S(1)/2, -0.1), Point(1,0), Point(0, 1)) assert poly1.intersection(poly2) == [Point2D(S(1)/3, 0), Segment(Point(0, S(1)/5), Point(0, 0)), Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(poly1) == [Point(S(1)/3, 0), Segment(Point(0, 0), Point(0, S(1)/5)), Segment(Point(1, 0), Point(0, 1))] assert poly1.intersection(Point(0, 0)) == [Point(0, 0)] assert poly1.intersection(Point(-12, -43)) == [] assert poly2.intersection(Line((-12, 0), (12, 0))) == [Point(-5, 0), Point(0, 0),Point(S(1)/3, 0), Point(1, 0)] assert poly2.intersection(Line((-12, 12), (12, 12))) == [] assert poly2.intersection(Ray((-3,4), (1,0))) == [Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(Circle((0, -1), 1)) == [Point(0, -2), Point(0, 0)] assert poly1.intersection(poly1) == [Segment(Point(0, 0), Point(1, 0)), Segment(Point(0, 1), Point(0, 0)), Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(poly2) == [Segment(Point(-5, 0), Point(0, -4)), Segment(Point(0, -4), Point(0, S(1)/5)), Segment(Point(0, S(1)/5), Point(S(1)/2, -S(1)/10)), Segment(Point(0, 1), Point(-5, 0)), Segment(Point(S(1)/2, -S(1)/10), Point(1, 0)), Segment(Point(1, 0), Point(0, 1))] assert poly2.intersection(Triangle(Point(0, 1), Point(1, 0), Point(-1, 1))) \ == [Point(-S(5)/7, S(6)/7), Segment(Point2D(0, 1), Point(1, 0))] assert poly1.intersection(RegularPolygon((-12, -15), 3, 3)) == []
class Geofence(object): #Takes in a file of coordinates y,x def __init__(self, filepath): log.info("Creating geofence...") self.polygon = None points = [] with open(filepath) as file: rows = csv.reader(file, delimiter=',') for row in rows: if len(row) != 2: log.info("Invalid point specificed: " + row) continue p = Point(float(row[0]), float(row[1]), evaluate=False) points.append(p) if len(points) == 2: p1 = Point(points[0].x, points[0].y, evaluate=False) p2 = Point(points[1].x, points[0].y, evaluate=False) p3 = Point(points[1].x, points[1].y, evaluate=False) p4 = Point(points[0].x, points[1].y, evaluate=False) self.polygon = Polygon(p1, p2, p3, p4) log.info(self.polygon) elif len(points) > 2: self.polygon = Polygon(*points) log.debug(self.polygon) log.info("Geofence established!") #Return true if x,y points are inside geofence def contains(self, x, y): rtn = self.polygon.encloses_point(Point(x,y, evaluate=False)) clear_cache() return rtn
def test_second_moment_of_area(): x, y = symbols('x, y') # triangle p1, p2, p3 = [(0, 0), (4, 0), (0, 2)] p = (0, 0) # equation of hypotenuse eq_y = (1-x/4)*2 I_yy = integrate((x**2) * (integrate(1, (y, 0, eq_y))), (x, 0, 4)) I_xx = integrate(1 * (integrate(y**2, (y, 0, eq_y))), (x, 0, 4)) I_xy = integrate(x * (integrate(y, (y, 0, eq_y))), (x, 0, 4)) triangle = Polygon(p1, p2, p3) assert (I_xx - triangle.second_moment_of_area(p)[0]) == 0 assert (I_yy - triangle.second_moment_of_area(p)[1]) == 0 assert (I_xy - triangle.second_moment_of_area(p)[2]) == 0 # rectangle p1, p2, p3, p4=[(0, 0), (4, 0), (4, 2), (0, 2)] I_yy = integrate((x**2) * integrate(1, (y, 0, 2)), (x, 0, 4)) I_xx = integrate(1 * integrate(y**2, (y, 0, 2)), (x, 0, 4)) I_xy = integrate(x * integrate(y, (y, 0, 2)), (x, 0, 4)) rectangle = Polygon(p1, p2, p3, p4) assert (I_xx - rectangle.second_moment_of_area(p)[0]) == 0 assert (I_yy - rectangle.second_moment_of_area(p)[1]) == 0 assert (I_xy - rectangle.second_moment_of_area(p)[2]) == 0
def __init__(self, filepath): log.info("Creating geofence...") self.polygon = None points = [] with open(filepath) as file: rows = csv.reader(file, delimiter=',') for row in rows: if len(row) != 2: log.info("Invalid point specificed: " + row) continue p = Point(float(row[0]), float(row[1]), evaluate=False) points.append(p) if len(points) == 2: p1 = Point(points[0].x, points[0].y, evaluate=False) p2 = Point(points[1].x, points[0].y, evaluate=False) p3 = Point(points[1].x, points[1].y, evaluate=False) p4 = Point(points[0].x, points[1].y, evaluate=False) self.polygon = Polygon(p1, p2, p3, p4) log.info(self.polygon) elif len(points) > 2: self.polygon = Polygon(*points) log.debug(self.polygon) log.info("Geofence established!")
x3 = Symbol('x3', real=True) y1 = Symbol('y1', real=True) y2 = Symbol('y2', real=True) y3 = Symbol('y3', real=True) z1 = Symbol('z1', real=True) z2 = Symbol('z2', real=True) z3 = Symbol('z3', real=True) half = Rational(1, 2) p1, p2, p3, p4 = map(Point, [(0, 0), (1, 0), (5, 1), (0, 1)]) p5, p6, p7 = map(Point, [(3, 2), (1, -1), (0, 2)]) l1 = Line(Point(0,0), Point(1,1)) l2 = Line(Point(half, half), Point(5,5)) l3 = Line(p2, p3) l4 = Line(p3, p4) poly1 = Polygon(p1, p2, p3, p4) poly2 = Polygon(p5, p6, p7) poly3 = Polygon(p1, p2, p5) def test_booleans(): """ test basic unions and intersections """ assert Union(l1, l2).equals(l1) assert Intersection(l1, l2).equals(l1) assert Intersection(l1, l4) == FiniteSet(Point(1,1)) assert Intersection(Union(l1, l4), l3) == FiniteSet(Point(-1/3, -1/3), Point(5, 1)) assert Intersection(l1, FiniteSet(Point(7,-7))) == EmptySet() assert Intersection(Circle(Point(0,0), 3), Line(p1,p2)) == FiniteSet(Point(-3,0), Point(3,0)) assert Intersection(l1, FiniteSet(p1)) == FiniteSet(p1) assert Union(l1, FiniteSet(p1)) == l1 fs = FiniteSet(Point(1/3, 1), Point(2/3, 0), Point(9/5, 1/5), Point(7/3, 1))
def test_transform(): pts = [Point(0, 0), Point(S(1)/2, S(1)/4), Point(1, 1)] pts_out = [Point(-4, -10), Point(-3, -S(37)/4), Point(-2, -7)] assert Triangle(*pts).scale(2, 3, (4, 5)) == Triangle(*pts_out) assert RegularPolygon((0, 0), 1, 4).scale(2, 3, (4, 5)) == \ Polygon(Point(-2, -10), Point(-4, -7), Point(-6, -10), Point(-4, -13))
def download_idaho_tiles_by_bbox(self, catId, bbox, resolution, outputfolder): '''Retrieve and view just the IDAHO chips in a particular bounding box for a catID. Args: catid (str): The source catalog ID from the platform catalog. bbox (list): List of coords: minx(W), miny(S), maxx(E), maxy(N). resolution (str): The desired floating point resolution of the tiles. outputfolder (str): The desired output location of the IDAHO tiles. ''' minx, miny, maxx, maxy = bbox #validate bbox values if (minx > maxx): print ('The west value is not less than the east value.') exit if (miny > maxy): print ('The south value is not less than the north value.') exit #create bbox polygon bp1 = Point(minx, miny) bp2 = Point(minx, maxy) bp3 = Point(maxx, maxy) bp4 = Point(maxx, miny) bbox_polygon = Polygon(bp1, bp2, bp3, bp4) #get IDAHO image results: parts idaho_image_results = self.get_images_by_catid(catId) description = self.describe_images(idaho_image_results) tile_count = 0 for catid, images in description.items(): for partnum, part in images['parts'].items(): num_images = len(list(part.keys())) partname = None if num_images == 1: # there is only one image, use the PAN partname = [p for p in list(part.keys()) if p.upper() == 'PAN'][0] elif num_images == 2: # there are two images in this part, use the multi (or pansharpen) partname = [p for p in list(part.keys()) if p is not 'PAN'][0] if not partname: print("Cannot find part for idaho image.") continue part_boundstr_wkt = part[partname]['boundstr'] part_polygon = geometry.from_wkt(part_boundstr_wkt) bucketname = part[partname]['bucket'] image_id = part[partname]['id'] W, S, E, N = part_polygon.bounds pp1, pp2, pp3, pp4 = Point(W, S), Point(W, N), Point(E, N), Point(E, S) part_bbox_polygon = Polygon(pp1, pp2, pp3, pp4) if (bbox_polygon.intersection(part_bbox_polygon)): center_lat = (S + old_div((N-S),2)) center_lon = (W + old_div((E-W),2)) print(center_lat, center_lon) self.get_idaho_chip(bucket_name=bucketname, idaho_id=image_id, center_lat=str(center_lat), center_lon=str(center_lon), resolution=resolution, output_folder=outputfolder) tile_count+=1 print ('There were ' + str(tile_count) + ' IDAHO images downloaded that ' + 'intersect with the provided bounding box.')
def test_polygon(): p1 = Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon(Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon(Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon(Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) # # General polygon # assert p1 == p2 assert len(p1) == Rational(6) assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2 * sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex( ) # ensure convex for both CW and CCW point specification # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) assert p1 != p2 assert p1.interior_angle == 3 * pi / 5 assert p1.exterior_angle == 2 * pi / 5 assert p2.apothem == 5 * cos(pi / 5) assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p1.is_convex() # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides s2 = t2.sides s3 = t3.sides # Basic stuff assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf() / 2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False # Bisectors bisectors = t1.bisectors assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125 * sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == 5 - 5 * 2**(S(1) / 2) / 2 assert t2.inradius == 5 * 3**(S(1) / 2) / 6 t3_inradius = (2 * x1**2 * Abs(x1) - 2**(S(1) / 2) * x1**2 * Abs(x1)) / (2 * x1**2) assert simplify((t3.inradius - t3_inradius)) == 0 # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1 / 2, x1 / 2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon(Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon(Point(0, Rational(5) / 4), Point(1, Rational(5) / 4), Point(1, Rational(9) / 4), Point(0, Rational(9) / 4)) p3 = Polygon(Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon(Point(1, 1), Point(Rational(6) / 5, 1), Point(1, Rational(6) / 5)) p5 = Polygon(Point(half, 3**(half) / 2), Point(-half, 3**(half) / 2), Point(-1, 0), Point(-half, -(3)**(half) / 2), Point(half, -(3)**(half) / 2), Point(1, 0)) p6 = Polygon(Point(2, Rational(3) / 10), Point(Rational(17) / 10, 0), Point(2, -Rational(3) / 10), Point(Rational(23) / 10, 0)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3) / 4 assert p3.distance(pt2) == sqrt(2) / 2 '''Polygon to Polygon''' assert p1.distance(p2) == half / 2 assert p1.distance(p3) == sqrt(2) / 2 assert p3.distance(p4) == (sqrt(2) / 2 - sqrt(Rational(2) / 25) / 2) assert p5.distance(p6) == Rational(7) / 10
def convex_hull(*args): """The convex hull surrounding the Points contained in the list of entities. Parameters ========== args : a collection of Points, Segments and/or Polygons Returns ======= convex_hull : Polygon Notes ===== This can only be performed on a set of non-symbolic points. References ========== [1] http://en.wikipedia.org/wiki/Graham_scan [2] Andrew's Monotone Chain Algorithm (A.M. Andrew, "Another Efficient Algorithm for Convex Hulls in Two Dimensions", 1979) http://softsurfer.com/Archive/algorithm_0109/algorithm_0109.htm See Also ======== sympy.geometry.point.Point, sympy.geometry.polygon.Polygon Examples ======== >>> from sympy.geometry import Point, convex_hull >>> points = [(1,1), (1,2), (3,1), (-5,2), (15,4)] >>> convex_hull(*points) Polygon(Point(-5, 2), Point(1, 1), Point(3, 1), Point(15, 4)) """ from .entity import GeometryEntity from .point import Point from .line import Segment from .polygon import Polygon p = set() for e in args: if not isinstance(e, GeometryEntity): try: e = Point(e) except NotImplementedError: raise ValueError('%s is not a GeometryEntity and cannot be made into Point' % str(e)) if isinstance(e, Point): p.add(e) elif isinstance(e, Segment): p.update(e.points) elif isinstance(e, Polygon): p.update(e.vertices) else: raise NotImplementedError( 'Convex hull for %s not implemented.' % type(e)) p = list(p) if len(p) == 1: return p[0] elif len(p) == 2: return Segment(p[0], p[1]) def _orientation(p, q, r): '''Return positive if p-q-r are clockwise, neg if ccw, zero if collinear.''' return (q.y - p.y)*(r.x - p.x) - (q.x - p.x)*(r.y - p.y) # scan to find upper and lower convex hulls of a set of 2d points. U = [] L = [] p.sort(key=lambda x: x.args) for p_i in p: while len(U) > 1 and _orientation(U[-2], U[-1], p_i) <= 0: U.pop() while len(L) > 1 and _orientation(L[-2], L[-1], p_i) >= 0: L.pop() U.append(p_i) L.append(p_i) U.reverse() convexHull = tuple(L + U[1:-1]) if len(convexHull) == 2: return Segment(convexHull[0], convexHull[1]) return Polygon(*convexHull)
def test_polygon(): t = Triangle(Point(0, 0), Point(2, 0), Point(3, 3)) assert Polygon(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 3)) == t assert Polygon(Point(1, 0), Point(2, 0), Point(3, 3), Point(0, 0)) == t assert Polygon(Point(2, 0), Point(3, 3), Point(0, 0), Point(1, 0)) == t p1 = Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon(Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon(Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon(Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) p5 = Polygon(Point(0, 0), Point(4, 4), Point(0, 4)) # # General polygon # assert p1 == p2 assert len(p1.args) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2 * sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex( ) # ensure convex for both CW and CCW point specification dict5 = p5.angles assert dict5[Point(0, 0)] == pi / 4 assert dict5[Point(0, 4)] == pi / 2 assert p5.encloses_point(Point(x, y)) == None assert p5.encloses_point(Point(1, 3)) assert p5.encloses_point(Point(0, 0)) == False assert p5.encloses_point(Point(4, 0)) == False p5.plot_interval('x') == [x, 0, 1] assert p5.distance(Polygon(Point(10, 10), Point(14, 14), Point(10, 14))) == 6 * sqrt(2) assert p5.distance( Polygon(Point(1, 8), Point(5, 8), Point(8, 12), Point(1, 12))) == 4 raises( UserWarning, lambda: Polygon(Point(0, 0), Point(1, 0), Point(1, 1)).distance( Polygon(Point(0, 0), Point(0, 1), Point(1, 1)))) assert hash(p5) == hash(Polygon(Point(0, 0), Point(4, 4), Point(0, 4))) assert p5 == Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) assert Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) in p5 assert p5 != Point(0, 4) assert Point(0, 1) in p5 assert p5.arbitrary_point('t').subs(Symbol('t', real=True), 0) == Point(0, 0) raises( ValueError, lambda: Polygon(Point(x, 0), Point(0, y), Point(x, y)). arbitrary_point('x')) # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), Point(0, 1), Point(1, 1))) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), 1, 2)) raises(ValueError, lambda: RegularPolygon(Point(0, 0), 1, 2.5)) assert p1 != p2 assert p1.interior_angle == 3 * pi / 5 assert p1.exterior_angle == 2 * pi / 5 assert p2.apothem == 5 * cos(pi / 5) assert p2.circumcenter == p1.circumcenter == Point(0, 0) assert p1.circumradius == p1.radius == 10 assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p2.inradius == p2.apothem == (5 * (1 + sqrt(5)) / 4) p2.spin(pi / 10) dict1 = p2.angles assert dict1[Point(0, 5)] == 3 * pi / 5 assert p1.is_convex() assert p1.rotation == 0 assert p1.encloses_point(Point(0, 0)) assert p1.encloses_point(Point(11, 0)) == False assert p2.encloses_point(Point(0, 4.9)) p1.spin(pi / 3) assert p1.rotation == pi / 3 assert p1.vertices[0] == Point(5, 5 * sqrt(3)) for var in p1.args: if isinstance(var, Point): assert var == Point(0, 0) else: assert var == 5 or var == 10 or var == pi / 3 assert p1 != Point(0, 0) assert p1 != p5 # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi / 3) == RegularPolygon(Point(0, 0), 10, 5, 2 * pi / 3) assert p1 == p1_old assert p1.area == (-250 * sqrt(5) + 1250) / (4 * tan(pi / 5)) assert p1.length == 20 * sqrt(-sqrt(5) / 8 + S(5) / 8) assert p1.scale(2, 2) == RegularPolygon(p1.center, p1.radius * 2, p1._n, p1.rotation) assert RegularPolygon((0, 0), 1, 4).scale(2, 3) == \ Polygon(Point(2, 0), Point(0, 3), Point(-2, 0), Point(0, -3)) assert ` p1 ` == str(p1) # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides assert Triangle(p1, p2, p1) == Polygon(p1, p2, p1) == Segment(p1, p2) raises(GeometryError, lambda: Triangle(Point(0, 0))) # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2 * 2, p2 * 3) == Segment(p2, p2 * 3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf() / 2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False assert t1.is_similar(Point(0, 0)) == False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125 * sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == t1.incircle.radius == 5 - 5 * sqrt(2) / 2 assert t2.inradius == t2.incircle.radius == 5 * sqrt(3) / 6 assert t3.inradius == t3.incircle.radius == x1**2 / ( (2 + sqrt(2)) * Abs(x1)) # Circumcircle assert t1.circumcircle.center == Point(2.5, 2.5) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1 / 2, x1 / 2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] assert t1.medial == Triangle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] assert t1.orthocenter == p1 t = S('''Triangle( Point(100080156402737/5000000000000, 79782624633431/500000000000), Point(39223884078253/2000000000000, 156345163124289/1000000000000), Point(31241359188437/1250000000000, 338338270939941/1000000000000000))''') assert t.orthocenter == S( '''Point(-780660869050599840216997''' '''79471538701955848721853/80368430960602242240789074233100000000000000,''' '''20151573611150265741278060334545897615974257/16073686192120448448157''' '''8148466200000000000)''') # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon(Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon(Point(0, Rational(5) / 4), Point(1, Rational(5) / 4), Point(1, Rational(9) / 4), Point(0, Rational(9) / 4)) p3 = Polygon(Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon(Point(1, 1), Point(Rational(6) / 5, 1), Point(1, Rational(6) / 5)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3) / 4 assert p3.distance(pt2) == sqrt(2) / 2
def convex_hull(*args, **kwargs): """The convex hull surrounding the Points contained in the list of entities. Parameters ========== args : a collection of Points, Segments and/or Polygons Returns ======= convex_hull : Polygon if ``polygon`` is True else as a tuple `(U, L)` where ``L`` and ``U`` are the lower and upper hulls, respectively. Notes ===== This can only be performed on a set of points whose coordinates can be ordered on the number line. References ========== [1] https://en.wikipedia.org/wiki/Graham_scan [2] Andrew's Monotone Chain Algorithm (A.M. Andrew, "Another Efficient Algorithm for Convex Hulls in Two Dimensions", 1979) http://geomalgorithms.com/a10-_hull-1.html See Also ======== sympy.geometry.point.Point, sympy.geometry.polygon.Polygon Examples ======== >>> from sympy.geometry import Point, convex_hull >>> points = [(1, 1), (1, 2), (3, 1), (-5, 2), (15, 4)] >>> convex_hull(*points) Polygon(Point2D(-5, 2), Point2D(1, 1), Point2D(3, 1), Point2D(15, 4)) >>> convex_hull(*points, **dict(polygon=False)) ([Point2D(-5, 2), Point2D(15, 4)], [Point2D(-5, 2), Point2D(1, 1), Point2D(3, 1), Point2D(15, 4)]) """ from .entity import GeometryEntity from .point import Point from .line import Segment from .polygon import Polygon polygon = kwargs.get('polygon', True) p = OrderedSet() for e in args: if not isinstance(e, GeometryEntity): try: e = Point(e) except NotImplementedError: raise ValueError('%s is not a GeometryEntity and cannot be made into Point' % str(e)) if isinstance(e, Point): p.add(e) elif isinstance(e, Segment): p.update(e.points) elif isinstance(e, Polygon): p.update(e.vertices) else: raise NotImplementedError( 'Convex hull for %s not implemented.' % type(e)) # make sure all our points are of the same dimension if any(len(x) != 2 for x in p): raise ValueError('Can only compute the convex hull in two dimensions') p = list(p) if len(p) == 1: return p[0] if polygon else (p[0], None) elif len(p) == 2: s = Segment(p[0], p[1]) return s if polygon else (s, None) def _orientation(p, q, r): '''Return positive if p-q-r are clockwise, neg if ccw, zero if collinear.''' return (q.y - p.y)*(r.x - p.x) - (q.x - p.x)*(r.y - p.y) # scan to find upper and lower convex hulls of a set of 2d points. U = [] L = [] try: p.sort(key=lambda x: x.args) except TypeError: raise ValueError("The points could not be sorted.") for p_i in p: while len(U) > 1 and _orientation(U[-2], U[-1], p_i) <= 0: U.pop() while len(L) > 1 and _orientation(L[-2], L[-1], p_i) >= 0: L.pop() U.append(p_i) L.append(p_i) U.reverse() convexHull = tuple(L + U[1:-1]) if len(convexHull) == 2: s = Segment(convexHull[0], convexHull[1]) return s if polygon else (s, None) if polygon: return Polygon(*convexHull) else: U.reverse() return (U, L)
def test_polygon(): t = Triangle(Point(0, 0), Point(2, 0), Point(3, 3)) assert Polygon(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 3)) == t assert Polygon(Point(1, 0), Point(2, 0), Point(3, 3), Point(0, 0)) == t assert Polygon(Point(2, 0), Point(3, 3), Point(0, 0), Point(1, 0)) == t p1 = Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon(Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon(Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon(Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) p5 = Polygon(Point(0, 0), Point(4, 4), Point(0, 4)) # # General polygon # assert p1 == p2 assert len(p1) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2 * sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex( ) # ensure convex for both CW and CCW point specification dict5 = p5.angles assert dict5[Point(0, 0)] == pi / 4 assert dict5[Point(0, 4)] == pi / 2 assert p5.encloses_point(Point(x, y)) == None assert p5.encloses_point(Point(1, 3)) assert p5.encloses_point(Point(0, 0)) == False assert p5.encloses_point(Point(4, 0)) == False p5.plot_interval('x') == [x, 0, 1] assert p5.distance(Polygon(Point(10, 10), Point(14, 14), Point(10, 14))) == 6 * sqrt(2) assert p5.distance( Polygon(Point(1, 8), Point(5, 8), Point(8, 12), Point(1, 12))) == 4 raises( UserWarning, 'Polygon(Point(0, 0), Point(1, 0), Point(1,1)).distance(Polygon(Point(0, 0), Point(0, 1), Point(1, 1)))' ) assert hash(p5) == hash(Polygon(Point(0, 0), Point(4, 4), Point(0, 4))) assert p5 == Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) assert Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) in p5 assert p5 != Point(0, 4) assert Point(0, 1) in p5 assert p5.arbitrary_point('t').subs(Symbol('t', real=True), 0) == Point(0, 0) raises( ValueError, "Polygon(Point(x, 0), Point(0, y), Point(x, y)).arbitrary_point('x')") # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) raises(GeometryError, 'RegularPolygon(Point(0, 0), Point(0, 1), Point(1, 1))') raises(GeometryError, 'RegularPolygon(Point(0, 0), 1, 2)') assert p1 != p2 assert p1.interior_angle == 3 * pi / 5 assert p1.exterior_angle == 2 * pi / 5 assert p2.apothem == 5 * cos(pi / 5) assert p2.circumcenter == p1.circumcenter == Point(0, 0) assert p1.circumradius == p1.radius == 10 assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p2.inradius == p2.apothem == (5 * (1 + sqrt(5)) / 4) p2.spin(pi / 10) dict1 = p2.angles assert dict1[Point(0, 5)] == 3 * pi / 5 assert p1.is_convex() assert p1.rotation == 0 assert p1.encloses_point(Point(0, 0)) assert p1.encloses_point(Point(11, 0)) == False assert p2.encloses_point(Point(0, 4.9)) p1.spin(pi / 3) assert p1.rotation == pi / 3 assert p1[0] == Point(5, 5 * sqrt(3)) for var in p1: if isinstance(var, Point): assert var == Point(0, 0) else: assert var == 5 or var == 10 or var == pi / 3 assert p1 != Point(0, 0) assert p1 != p5 raises(IndexError, 'RegularPolygon(Point(0, 0), 1, 3)[4]') # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi / 3) == RegularPolygon(Point(0, 0), 10, 5, 2 * pi / 3) assert p1 == p1_old assert ` p1 ` == str(p1) # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides assert Triangle(p1, p2, p1) == Polygon(p1, p2, p1) == Segment(p1, p2) raises(GeometryError, 'Triangle(Point(0, 0))') # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2 * 2, p2 * 3) == Segment(p2, p2 * 3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf() / 2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False assert t1.is_similar(Point(0, 0)) == False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125 * sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == t1.incircle.radius == 5 - 5 * sqrt(2) / 2 assert t2.inradius == t2.incircle.radius == 5 * sqrt(3) / 6 assert t3.inradius == t3.incircle.radius == x1**2 / ( (2 + sqrt(2)) * Abs(x1)) # Circumcircle assert t1.circumcircle.center == Point(2.5, 2.5) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1 / 2, x1 / 2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] assert t1.medial == Triangle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] assert t1.orthocenter == p1 # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon(Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon(Point(0, Rational(5) / 4), Point(1, Rational(5) / 4), Point(1, Rational(9) / 4), Point(0, Rational(9) / 4)) p3 = Polygon(Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon(Point(1, 1), Point(Rational(6) / 5, 1), Point(1, Rational(6) / 5)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3) / 4 assert p3.distance(pt2) == sqrt(2) / 2
def test_cross_section(): I = Symbol('I') l = Symbol('l') E = Symbol('E') C3, C4 = symbols('C3, C4') a, c, g, h, r, n = symbols('a, c, g, h, r, n') # test for second_moment and cross_section setter b0 = Beam(l, E, I) assert b0.second_moment == I assert b0.cross_section == None b0.cross_section = Circle((0, 0), 5) assert b0.second_moment == pi * Rational(625, 4) assert b0.cross_section == Circle((0, 0), 5) b0.second_moment = 2 * n - 6 assert b0.second_moment == 2 * n - 6 assert b0.cross_section == None with raises(ValueError): b0.second_moment = Circle((0, 0), 5) # beam with a circular cross-section b1 = Beam(50, E, Circle((0, 0), r)) assert b1.cross_section == Circle((0, 0), r) assert b1.second_moment == pi * r * Abs(r)**3 / 4 b1.apply_load(-10, 0, -1) b1.apply_load(R1, 5, -1) b1.apply_load(R2, 50, -1) b1.apply_load(90, 45, -2) b1.solve_for_reaction_loads(R1, R2) assert b1.load == (-10 * SingularityFunction(x, 0, -1) + 82 * SingularityFunction(x, 5, -1) / S(9) + 90 * SingularityFunction(x, 45, -2) + 8 * SingularityFunction(x, 50, -1) / 9) assert b1.bending_moment() == (-10 * SingularityFunction(x, 0, 1) + 82 * SingularityFunction(x, 5, 1) / 9 + 90 * SingularityFunction(x, 45, 0) + 8 * SingularityFunction(x, 50, 1) / 9) q = (-5 * SingularityFunction(x, 0, 2) + 41 * SingularityFunction(x, 5, 2) / S(9) + 90 * SingularityFunction(x, 45, 1) + 4 * SingularityFunction(x, 50, 2) / S(9)) / (pi * E * r * Abs(r)**3) assert b1.slope() == C3 + 4 * q q = (-5 * SingularityFunction(x, 0, 3) / 3 + 41 * SingularityFunction(x, 5, 3) / 27 + 45 * SingularityFunction(x, 45, 2) + 4 * SingularityFunction(x, 50, 3) / 27) / (pi * E * r * Abs(r)**3) assert b1.deflection() == C3 * x + C4 + 4 * q # beam with a recatangular cross-section b2 = Beam(20, E, Polygon((0, 0), (a, 0), (a, c), (0, c))) assert b2.cross_section == Polygon((0, 0), (a, 0), (a, c), (0, c)) assert b2.second_moment == a * c**3 / 12 # beam with a triangular cross-section b3 = Beam(15, E, Triangle((0, 0), (g, 0), (g / 2, h))) assert b3.cross_section == Triangle(Point2D(0, 0), Point2D(g, 0), Point2D(g / 2, h)) assert b3.second_moment == g * h**3 / 36 # composite beam b = b2.join(b3, "fixed") b.apply_load(-30, 0, -1) b.apply_load(65, 0, -2) b.apply_load(40, 0, -1) b.bc_slope = [(0, 0)] b.bc_deflection = [(0, 0)] assert b.second_moment == Piecewise((a * c**3 / 12, x <= 20), (g * h**3 / 36, x <= 35)) assert b.cross_section == None assert b.length == 35 assert b.slope().subs(x, 7) == 8400 / (E * a * c**3) assert b.slope().subs( x, 25) == 52200 / (E * g * h**3) + 39600 / (E * a * c**3) assert b.deflection().subs( x, 30) == 537000 / (E * g * h**3) + 712000 / (E * a * c**3)
def test_polygon(): p1 = Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon(Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon(Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon(Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) # # General polygon # assert p1 == p2 assert len(p1) == Rational(6) assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2 * sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex( ) # ensure convex for both CW and CCW point specification # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) assert p1 != p2 assert p1.interior_angle == 3 * pi / 5 assert p1.exterior_angle == 2 * pi / 5 assert p2.apothem == 5 * cos(pi / 5) assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p1.is_convex() # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides s2 = t2.sides s3 = t3.sides # Basic stuff assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf() / 2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False # Bisectors bisectors = t1.bisectors assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125 * sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1 / 2, x1 / 2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1
def download_idaho_tiles_by_bbox(self, catId, bbox, resolution, outputfolder): '''Retrieve and view just the IDAHO chips in a particular bounding box for a catID. Args: catid (str): The source catalog ID from the platform catalog. bbox (list): List of coords: minx(W), miny(S), maxx(E), maxy(N). resolution (str): The desired floating point resolution of the tiles. outputfolder (str): The desired output location of the IDAHO tiles. ''' minx, miny, maxx, maxy = bbox #validate bbox values if (minx > maxx): print('The west value is not less than the east value.') exit if (miny > maxy): print('The south value is not less than the north value.') exit #create bbox polygon bp1 = Point(minx, miny) bp2 = Point(minx, maxy) bp3 = Point(maxx, maxy) bp4 = Point(maxx, miny) bbox_polygon = Polygon(bp1, bp2, bp3, bp4) #get IDAHO image results: parts idaho_image_results = self.get_images_by_catid(catId) description = self.describe_images(idaho_image_results) tile_count = 0 for catid, images in description.items(): for partnum, part in images['parts'].items(): num_images = len(list(part.keys())) partname = None if num_images == 1: # there is only one image, use the PAN partname = [ p for p in list(part.keys()) if p.upper() == 'PAN' ][0] elif num_images == 2: # there are two images in this part, use the multi (or pansharpen) partname = [ p for p in list(part.keys()) if p is not 'PAN' ][0] if not partname: print("Cannot find part for idaho image.") continue part_boundstr_wkt = part[partname]['boundstr'] part_polygon = geometry.from_wkt(part_boundstr_wkt) bucketname = part[partname]['bucket'] image_id = part[partname]['id'] W, S, E, N = part_polygon.bounds pp1, pp2, pp3, pp4 = Point(W, S), Point(W, N), Point(E, N), Point(E, S) part_bbox_polygon = Polygon(pp1, pp2, pp3, pp4) if (bbox_polygon.intersection(part_bbox_polygon)): center_lat = (S + old_div((N - S), 2)) center_lon = (W + old_div((E - W), 2)) print(center_lat, center_lon) self.get_idaho_chip(bucket_name=bucketname, idaho_id=image_id, center_lat=str(center_lat), center_lon=str(center_lon), resolution=resolution, output_folder=outputfolder) tile_count += 1 print('There were ' + str(tile_count) + ' IDAHO images downloaded that ' + 'intersect with the provided bounding box.')
def view_idaho_tiles_by_bbox(self, catId, bbox, output_filename): '''Retrieve and view just the IDAHO chips in a particular bounding box for a catID. Args: catid (str): The source catalog ID from the platform catalog. bbox (list): List of coords: minx(W), miny(S), maxx(E), maxy(N). output_filename (str): a Leaflet Viewer file showing the IDAHO images as tiles. ''' minx, miny, maxx, maxy = bbox #validate bbox values if (minx > maxx): print('The west value is not less than the east value.') exit if (miny > maxy): print('The south value is not less than the north value.') exit #create bbox polygon bp1 = Point(minx, miny) bp2 = Point(minx, maxy) bp3 = Point(maxx, maxy) bp4 = Point(maxx, miny) bbox_polygon = Polygon(bp1, bp2, bp3, bp4) #get IDAHO image results: parts idaho_image_results = self.get_images_by_catid(catId) description = self.describe_images(idaho_image_results) tile_count = 0 for catid, images in description.items(): functionstring = '' for partnum, part in images['parts'].items(): num_images = len(list(part.keys())) partname = None if num_images == 1: # there is only one image, use the PAN partname = [ p for p in list(part.keys()) if p.upper() == 'PAN' ][0] pan_image_id = '' elif num_images == 2: # there are two images in this part, use the multi (or pansharpen) partname = [ p for p in list(part.keys()) if p is not 'PAN' ][0] pan_image_id = part['PAN']['id'] if not partname: print("Cannot find part for idaho image.") continue bandstr = { 'RGBN': '0,1,2', 'WORLDVIEW_8_BAND': '4,2,1', 'PAN': '0' }.get(partname, '0,1,2') part_boundstr_wkt = part[partname]['boundstr'] part_polygon = geometry.from_wkt(part_boundstr_wkt) bucketname = part[partname]['bucket'] image_id = part[partname]['id'] W, S, E, N = part_polygon.bounds pp1, pp2, pp3, pp4 = Point(W, S), Point(W, N), Point(E, N), Point(E, S) part_bbox_polygon = Polygon(pp1, pp2, pp3, pp4) if (bbox_polygon.intersection(part_bbox_polygon)): functionstring += ( "addLayerToMap('%s','%s',%s,%s,%s,%s,'%s');\n" % (bucketname, image_id, W, S, E, N, pan_image_id)) tile_count += 1 print('There were ' + str(tile_count) + ' IDAHO images found to ' + 'intersect with the provided bounding box.') __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(os.path.realpath('__file__')))) with open(os.path.join(__location__, 'leafletmap_template.html'), 'r') as htmlfile: data = htmlfile.read().decode("utf8") data = data.replace('FUNCTIONSTRING', functionstring) data = data.replace('CENTERLAT', str(S + old_div((N - S), 2))) data = data.replace('CENTERLON', str(W + old_div((E - W), 2))) data = data.replace('BANDS', bandstr) data = data.replace('TOKEN', self.gbdx_connection.access_token) with codecs.open(output_filename, 'w', 'utf8') as outputfile: print("Saving %s" % output_filename) outputfile.write(data)
def polytope_integrate(poly, expr=None, **kwargs): """Integrates polynomials over 2/3-Polytopes. This function accepts the polytope in `poly` and the function in `expr` (uni/bi/trivariate polynomials are implemented) and returns the exact integral of `expr` over `poly`. Parameters ========== poly : The input Polygon. expr : The input polynomial. clockwise : Binary value to sort input points of 2-Polytope clockwise.(Optional) max_degree : The maximum degree of any monomial of the input polynomial.(Optional) Examples ======== >>> from sympy.abc import x, y >>> from sympy.geometry.polygon import Polygon >>> from sympy.geometry.point import Point >>> from sympy.integrals.intpoly import polytope_integrate >>> polygon = Polygon(Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0)) >>> polys = [1, x, y, x*y, x**2*y, x*y**2] >>> expr = x*y >>> polytope_integrate(polygon, expr) 1/4 >>> polytope_integrate(polygon, polys, max_degree=3) {1: 1, x: 1/2, y: 1/2, x*y: 1/4, x*y**2: 1/6, x**2*y: 1/6} """ clockwise = kwargs.get('clockwise', False) max_degree = kwargs.get('max_degree', None) if clockwise: if isinstance(poly, Polygon): poly = Polygon(*point_sort(poly.vertices), evaluate=False) else: raise TypeError("clockwise=True works for only 2-Polytope" "V-representation input") if isinstance(poly, Polygon): # For Vertex Representation(2D case) hp_params = hyperplane_parameters(poly) facets = poly.sides elif len(poly[0]) == 2: # For Hyperplane Representation(2D case) plen = len(poly) if len(poly[0][0]) == 2: intersections = [intersection(poly[(i - 1) % plen], poly[i], "plane2D") for i in range(0, plen)] hp_params = poly lints = len(intersections) facets = [Segment2D(intersections[i], intersections[(i + 1) % lints]) for i in range(0, lints)] else: raise NotImplementedError("Integration for H-representation 3D" "case not implemented yet.") else: # For Vertex Representation(3D case) vertices = poly[0] facets = poly[1:] hp_params = hyperplane_parameters(facets, vertices) if max_degree is None: if expr is None: raise TypeError('Input expression be must' 'be a valid SymPy expression') return main_integrate3d(expr, facets, vertices, hp_params) if max_degree is not None: result = {} if not isinstance(expr, list) and expr is not None: raise TypeError('Input polynomials must be list of expressions') if len(hp_params[0][0]) == 3: result_dict = main_integrate3d(0, facets, vertices, hp_params, max_degree) else: result_dict = main_integrate(0, facets, hp_params, max_degree) if expr is None: return result_dict for poly in expr: poly = _sympify(poly) if poly not in result: if poly.is_zero: result[S.Zero] = S.Zero continue integral_value = S.Zero monoms = decompose(poly, separate=True) for monom in monoms: monom = nsimplify(monom) coeff, m = strip(monom) integral_value += result_dict[m] * coeff result[poly] = integral_value return result if expr is None: raise TypeError('Input expression be must' 'be a valid SymPy expression') return main_integrate(expr, facets, hp_params)
def time_create(self): "Creating Polygon" Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5))
def test_first_moment(): a, b = symbols('a, b', positive=True) # rectangle p1 = Polygon((0, 0), (a, 0), (a, b), (0, b)) assert p1.first_moment_of_area() == (a*b**2/8, a**2*b/8) assert p1.first_moment_of_area((a/3, b/4)) == (-3*a*b**2/32, -a**2*b/9) p1 = Polygon((0, 0), (40, 0), (40, 30), (0, 30)) assert p1.first_moment_of_area() == (4500, 6000) # triangle p2 = Polygon((0, 0), (a, 0), (a/2, b)) assert p2.first_moment_of_area() == (4*a*b**2/81, a**2*b/24) assert p2.first_moment_of_area((a/8, b/6)) == (-25*a*b**2/648, -5*a**2*b/768) p2 = Polygon((0, 0), (12, 0), (12, 30)) p2.first_moment_of_area() == (1600/3, -640/3)
from __future__ import print_function, division from distutils.version import LooseVersion from sympy import Rational import sympy from sympy.geometry import (Line, Point, Polygon) from random import randint listOfPolygons = [ Polygon(Point(0 + w, 0 + w), Point(3 + w, 0 + w), Point(3 + w, 3 + w), Point(0 + w, 3 + w)) for w in range(10) ] cutListOfPolygons = [ Polygon((-1, -1), (1, Rational(5, 2)), (2, 1), (3, Rational(5, 2)), (4, 2), (5, 3), (-1, 3)) for w in range(10) ] cutLines = [Line((0, 0), (Rational(9, 2), 3)) for w in range(10)] class PolygonAttributes: def time_create(self): "Creating Polygon" Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5)) def time_area(self): "Polygon.area for w in range(10)" [listOfPolygons[w].area for w in range(10)] def time_perimeter(self): "Polygon.perimeter for w in range(10)" [listOfPolygons[w].perimeter for w in range(10)] def time_sides(self):
def test_polygon(): t = Triangle(Point(0, 0), Point(2, 0), Point(3, 3)) assert Polygon(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 3)) == t assert Polygon(Point(1, 0), Point(2, 0), Point(3, 3), Point(0, 0)) == t assert Polygon(Point(2, 0), Point(3, 3), Point(0, 0), Point(1, 0)) == t p1 = Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon(Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon(Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon(Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) # # General polygon # assert p1 == p2 assert len(p1) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2 * sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex() # ensure convex for both CW and CCW point specification # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) assert p1 != p2 assert p1.interior_angle == 3 * pi / 5 assert p1.exterior_angle == 2 * pi / 5 assert p2.apothem == 5 * cos(pi / 5) assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p1.is_convex() # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides s2 = t2.sides s3 = t3.sides # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2 * 2, p2 * 3) == Segment(p2, p2 * 3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf() / 2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125 * sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == 5 - 5 * sqrt(2) / 2 assert t2.inradius == 5 * sqrt(3) / 6 assert t3.inradius == x1 ** 2 / ((2 + sqrt(2)) * Abs(x1)) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1 / 2, x1 / 2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon(Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5) / 4), Point(1, Rational(5) / 4), Point(1, Rational(9) / 4), Point(0, Rational(9) / 4) ) p3 = Polygon(Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon(Point(1, 1), Point(Rational(6) / 5, 1), Point(1, Rational(6) / 5)) p5 = Polygon( Point(half, 3 ** (half) / 2), Point(-half, 3 ** (half) / 2), Point(-1, 0), Point(-half, -(3) ** (half) / 2), Point(half, -(3) ** (half) / 2), Point(1, 0), ) p6 = Polygon( Point(2, Rational(3) / 10), Point(Rational(17) / 10, 0), Point(2, -Rational(3) / 10), Point(Rational(23) / 10, 0), ) pt1 = Point(half, half) pt2 = Point(1, 1) """Polygon to Point""" assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3) / 4 assert p3.distance(pt2) == sqrt(2) / 2 """Polygon to Polygon""" import warnings # p1.distance(p2) emits a warning # First, test the warning warnings.filterwarnings("error", "Polygons may intersect producing erroneous output") raises(UserWarning, "p1.distance(p2)") # now test the actual output warnings.filterwarnings("ignore", "Polygons may intersect producing erroneous output") assert p1.distance(p2) == half / 2 # Keep testing reasonably thread safe, so reset the warning warnings.filterwarnings("default", "Polygons may intersect producing erroneous output") # Note, in Python 2.6+, this can be done more nicely using the # warnings.catch_warnings context manager. # See http://docs.python.org/library/warnings#testing-warnings. assert p1.distance(p3) == sqrt(2) / 2 assert p3.distance(p4) == (sqrt(2) / 2 - sqrt(Rational(2) / 25) / 2) assert p5.distance(p6) == Rational(7) / 10
def test_polygon(): t = Triangle(Point(0, 0), Point(2, 0), Point(3, 3)) assert Polygon(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 3)) == t assert Polygon(Point(1, 0), Point(2, 0), Point(3, 3), Point(0, 0)) == t assert Polygon(Point(2, 0), Point(3, 3), Point(0, 0), Point(1, 0)) == t p1 = Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon(Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon(Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon(Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) # # General polygon # assert p1 == p2 assert len(p1) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2 * sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex( ) # ensure convex for both CW and CCW point specification # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) assert p1 != p2 assert p1.interior_angle == 3 * pi / 5 assert p1.exterior_angle == 2 * pi / 5 assert p2.apothem == 5 * cos(pi / 5) assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p1.is_convex() assert p1.rotation == 0 p1.spin(pi / 3) assert p1.rotation == pi / 3 assert p1[0] == Point(5, 5 * sqrt(3)) # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi / 3) == RegularPolygon(Point(0, 0), 10, 5, 2 * pi / 3) assert p1 == p1_old # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides s2 = t2.sides s3 = t3.sides # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2 * 2, p2 * 3) == Segment(p2, p2 * 3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf() / 2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125 * sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == 5 - 5 * sqrt(2) / 2 assert t2.inradius == 5 * sqrt(3) / 6 assert t3.inradius == x1**2 / ((2 + sqrt(2)) * Abs(x1)) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1 / 2, x1 / 2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon(Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon(Point(0, Rational(5) / 4), Point(1, Rational(5) / 4), Point(1, Rational(9) / 4), Point(0, Rational(9) / 4)) p3 = Polygon(Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon(Point(1, 1), Point(Rational(6) / 5, 1), Point(1, Rational(6) / 5)) p5 = Polygon(Point(half, 3**(half) / 2), Point(-half, 3**(half) / 2), Point(-1, 0), Point(-half, -(3)**(half) / 2), Point(half, -(3)**(half) / 2), Point(1, 0)) p6 = Polygon(Point(2, Rational(3) / 10), Point(Rational(17) / 10, 0), Point(2, -Rational(3) / 10), Point(Rational(23) / 10, 0)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3) / 4 assert p3.distance(pt2) == sqrt(2) / 2 '''Polygon to Polygon''' import warnings # p1.distance(p2) emits a warning # First, test the warning warnings.filterwarnings( "error", "Polygons may intersect producing erroneous output") raises(UserWarning, "p1.distance(p2)") # now test the actual output warnings.filterwarnings( "ignore", "Polygons may intersect producing erroneous output") assert p1.distance(p2) == half / 2 # Keep testing reasonably thread safe, so reset the warning warnings.filterwarnings( "default", "Polygons may intersect producing erroneous output") # Note, in Python 2.6+, this can be done more nicely using the # warnings.catch_warnings context manager. # See http://docs.python.org/library/warnings#testing-warnings. assert p1.distance(p3) == sqrt(2) / 2 assert p3.distance(p4) == (sqrt(2) / 2 - sqrt(Rational(2) / 25) / 2) assert p5.distance(p6) == Rational(7) / 10
def test_polygon(): p1 = Polygon( Point(0, 0), Point(3,-1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon( Point(6, 0), Point(3,-1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon( Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon( Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) # # General polygon # assert p1 == p2 assert len(p1) == Rational(6) assert len(p1.sides) == 6 assert p1.perimeter == 5+2*sqrt(10)+sqrt(29)+sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex() # ensure convex for both CW and CCW point specification # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) assert p1 != p2 assert p1.interior_angle == 3*pi/5 assert p1.exterior_angle == 2*pi/5 assert p2.apothem == 5*cos(pi/5) assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p1.is_convex() # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Real("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Real("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Real("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Real("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5,2), sqrt(Rational(75,4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides s2 = t2.sides s3 = t3.sides # Basic stuff assert t1.area == Rational(25,2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf()/2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False # Bisectors bisectors = t1.bisectors assert bisectors[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) ic = (250 - 125*sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == 5 - 5*2**(S(1)/2)/2 assert t2.inradius == 5*3**(S(1)/2)/6 assert t3.inradius == (2*x1**2*Abs(x1) - 2**(S(1)/2)*x1**2*Abs(x1))/(2*x1**2) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5,3), Rational(5,3)) assert m[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) assert t3.medians[p1] == Segment(p1, Point(x1/2, x1/2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon( Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5)/4), Point(1, Rational(5)/4), Point(1, Rational(9)/4), Point(0, Rational(9)/4)) p3 = Polygon( Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon( Point(1, 1), Point(Rational(6)/5, 1), Point(1, Rational(6)/5)) p5 = Polygon( Point(half, 3**(half)/2), Point(-half, 3**(half)/2), Point(-1, 0), Point(-half, -(3)**(half)/2), Point(half, -(3)**(half)/2), Point(1, 0)) p6 = Polygon(Point(2, Rational(3)/10), Point(Rational(17)/10, 0), Point(2, -Rational(3)/10), Point(Rational(23)/10, 0)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3)/4 assert p3.distance(pt2) == sqrt(2)/2 '''Polygon to Polygon''' assert p1.distance(p2) == half/2 assert p1.distance(p3) == sqrt(2)/2 assert p3.distance(p4) == (sqrt(2)/2 - sqrt(Rational(2)/25)/2) assert p5.distance(p6) == Rational(7)/10
def test_ellipse(): p1 = Point(0, 0) p2 = Point(1, 1) p4 = Point(0, 1) e1 = Ellipse(p1, 1, 1) e2 = Ellipse(p2, half, 1) e3 = Ellipse(p1, y1, y1) c1 = Circle(p1, 1) c2 = Circle(p2, 1) c3 = Circle(Point(sqrt(2), sqrt(2)), 1) # Test creation with three points cen, rad = Point(3 * half, 2), 5 * half assert Circle(Point(0, 0), Point(3, 0), Point(0, 4)) == Circle(cen, rad) raises(GeometryError, lambda: Circle(Point(0, 0), Point(1, 1), Point(2, 2))) raises(ValueError, lambda: Ellipse(None, None, None, 1)) raises(GeometryError, lambda: Circle(Point(0, 0))) # Basic Stuff assert Ellipse(None, 1, 1).center == Point(0, 0) assert e1 == c1 assert e1 != e2 assert p4 in e1 assert p2 not in e2 assert e1.area == pi assert e2.area == pi / 2 assert e3.area == pi * (y1**2) assert c1.area == e1.area assert c1.circumference == e1.circumference assert e3.circumference == 2 * pi * y1 assert e1.plot_interval() == e2.plot_interval() == [t, -pi, pi] assert e1.plot_interval(x) == e2.plot_interval(x) == [x, -pi, pi] assert Ellipse(None, 1, None, 1).circumference == 2 * pi assert c1.minor == 1 assert c1.major == 1 assert c1.hradius == 1 assert c1.vradius == 1 # Private Functions assert hash(c1) == hash(Circle(Point(1, 0), Point(0, 1), Point(0, -1))) assert c1 in e1 assert (Line(p1, p2) in e1) == False assert e1.__cmp__(e1) == 0 assert e1.__cmp__(Point(0, 0)) > 0 # Encloses assert e1.encloses(Segment(Point(-0.5, -0.5), Point(0.5, 0.5))) == True assert e1.encloses(Line(p1, p2)) == False assert e1.encloses(Ray(p1, p2)) == False assert e1.encloses(e1) == False assert e1.encloses( Polygon(Point(-0.5, -0.5), Point(-0.5, 0.5), Point(0.5, 0.5))) == True assert e1.encloses(RegularPolygon(p1, 0.5, 3)) == True assert e1.encloses(RegularPolygon(p1, 5, 3)) == False assert e1.encloses(RegularPolygon(p2, 5, 3)) == False # with generic symbols, the hradius is assumed to contain the major radius M = Symbol('M') m = Symbol('m') c = Ellipse(p1, M, m).circumference _x = c.atoms(Dummy).pop() assert c == \ 4*M*C.Integral(sqrt((1 - _x**2*(M**2 - m**2)/M**2)/(1 - _x**2)), (_x, 0, 1)) assert e2.arbitrary_point() in e2 # Foci f1, f2 = Point(sqrt(12), 0), Point(-sqrt(12), 0) ef = Ellipse(Point(0, 0), 4, 2) assert ef.foci in [(f1, f2), (f2, f1)] # Tangents v = sqrt(2) / 2 p1_1 = Point(v, v) p1_2 = p2 + Point(half, 0) p1_3 = p2 + Point(0, 1) assert e1.tangent_lines(p4) == c1.tangent_lines(p4) assert e2.tangent_lines(p1_2) == [Line(p1_2, p2 + Point(half, 1))] assert e2.tangent_lines(p1_3) == [Line(p1_3, p2 + Point(half, 1))] assert c1.tangent_lines(p1_1) == [Line(p1_1, Point(0, sqrt(2)))] assert c1.tangent_lines(p1) == [] assert e2.is_tangent(Line(p1_2, p2 + Point(half, 1))) assert e2.is_tangent(Line(p1_3, p2 + Point(half, 1))) assert c1.is_tangent(Line(p1_1, Point(0, sqrt(2)))) assert e1.is_tangent(Line(Point(0, 0), Point(1, 1))) == False assert c1.is_tangent(e1) == False assert c1.is_tangent(Ellipse(Point(2, 0), 1, 1)) == True assert c1.is_tangent(Polygon(Point(1, 1), Point(1, -1), Point(2, 0))) == True assert c1.is_tangent(Polygon(Point(1, 1), Point(1, 0), Point(2, 0))) == False assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(S(77)/25, S(132)/25)), Line(Point(0, 0), Point(S(33)/5, S(22)/5))] assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(3, 4)) == \ [Line(Point(3, 4), Point(4, 4)), Line(Point(3, 4), Point(3, 5))] assert Circle(Point(5, 5), 2).tangent_lines(Point(3, 3)) == \ [Line(Point(3, 3), Point(4, 3)), Line(Point(3, 3), Point(3, 4))] assert Circle(Point(5, 5), 2).tangent_lines(Point(5 - 2*sqrt(2), 5)) == \ [Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 - sqrt(2))), Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 + sqrt(2))),] # Properties major = 3 minor = 1 e4 = Ellipse(p2, minor, major) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major * (1 - ecc) assert e4.apoapsis == major * (1 + ecc) # independent of orientation e4 = Ellipse(p2, major, minor) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major * (1 - ecc) assert e4.apoapsis == major * (1 + ecc) # Intersection l1 = Line(Point(1, -5), Point(1, 5)) l2 = Line(Point(-5, -1), Point(5, -1)) l3 = Line(Point(-1, -1), Point(1, 1)) l4 = Line(Point(-10, 0), Point(0, 10)) pts_c1_l3 = [ Point(sqrt(2) / 2, sqrt(2) / 2), Point(-sqrt(2) / 2, -sqrt(2) / 2) ] assert intersection(e2, l4) == [] assert intersection(c1, Point(1, 0)) == [Point(1, 0)] assert intersection(c1, l1) == [Point(1, 0)] assert intersection(c1, l2) == [Point(0, -1)] assert intersection(c1, l3) in [pts_c1_l3, [pts_c1_l3[1], pts_c1_l3[0]]] assert intersection(c1, c2) == [Point(0, 1), Point(1, 0)] assert intersection(c1, c3) == [Point(sqrt(2) / 2, sqrt(2) / 2)] assert e1.intersection(l1) == [Point(1, 0)] assert e2.intersection(l4) == [] assert e1.intersection(Circle(Point(0, 2), 1)) == [Point(0, 1)] assert e1.intersection(Circle(Point(5, 0), 1)) == [] assert e1.intersection(Ellipse(Point(2, 0), 1, 1)) == [Point(1, 0)] assert e1.intersection(Ellipse( Point(5, 0), 1, 1, )) == [] assert e1.intersection(Point(2, 0)) == [] assert e1.intersection(e1) == e1 # some special case intersections csmall = Circle(p1, 3) cbig = Circle(p1, 5) cout = Circle(Point(5, 5), 1) # one circle inside of another assert csmall.intersection(cbig) == [] # separate circles assert csmall.intersection(cout) == [] # coincident circles assert csmall.intersection(csmall) == csmall v = sqrt(2) t1 = Triangle(Point(0, v), Point(0, -v), Point(v, 0)) points = intersection(t1, c1) assert len(points) == 4 assert Point(0, 1) in points assert Point(0, -1) in points assert Point(v / 2, v / 2) in points assert Point(v / 2, -v / 2) in points circ = Circle(Point(0, 0), 5) elip = Ellipse(Point(0, 0), 5, 20) assert intersection(circ, elip) in \ [[Point(5, 0), Point(-5, 0)], [Point(-5, 0), Point(5, 0)]] assert elip.tangent_lines(Point(0, 0)) == [] elip = Ellipse(Point(0, 0), 3, 2) assert elip.tangent_lines(Point(3, 0)) == [Line(Point(3, 0), Point(3, -12))] e1 = Ellipse(Point(0, 0), 5, 10) e2 = Ellipse(Point(2, 1), 4, 8) a = S(53) / 17 c = 2 * sqrt(3991) / 17 ans = [Point(a - c / 8, a / 2 + c), Point(a + c / 8, a / 2 - c)] assert e1.intersection(e2) == ans e2 = Ellipse(Point(x, y), 4, 8) assert [p.subs({x: 2, y: 1}) for p in e1.intersection(e2)] == ans # Combinations of above assert e3.is_tangent(e3.tangent_lines(p1 + Point(y1, 0))[0]) e = Ellipse((1, 2), 3, 2) assert e.tangent_lines(Point(10, 0)) == \ [Line(Point(10, 0), Point(1, 0)), Line(Point(10, 0), Point(S(14)/5, S(18)/5))] # encloses_point e = Ellipse((0, 0), 1, 2) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point(e.center + Point(e.hradius + Rational(1, 10), 0)) is False e = Ellipse((0, 0), 2, 1) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point(e.center + Point(e.hradius + Rational(1, 10), 0)) is False assert c1.encloses_point(Point(1, 0)) is False assert c1.encloses_point(Point(0.3, 0.4)) is True assert e.scale(2, 3) == Ellipse((0, 0), 4, 3) assert e.scale(3, 6) == Ellipse((0, 0), 6, 6) assert e.rotate(pi / 3) == e assert e.rotate(pi/3, (1, 2)) == \ Ellipse(Point(S(1)/2 + sqrt(3), -sqrt(3)/2 + 1), 2, 1)
def threeIps(self): # Get center from input sympy geometry library if not self.Circle.cirValues["c"] and self.Triangle.GeoT: p = self.Triangle.GeoT.incenter self.Circle.cirValues["c"] = (float(p[0]), float(p[1])) # Get radius from input sympy geometry library if not self.Circle.cirValues["r"] and self.Triangle.GeoT: self.Circle.cirValues["r"] = abs(float( self.Triangle.GeoT.inradius)) # Get Intersection points from input sympy geometry library if self.getIPs() != 3 and self.Triangle.GeoT: points = intersection(self.Triangle.GeoT.incircle, self.Triangle.GeoT) s1 = Segment(self.get_value("v2"), self.get_value("v3")) s2 = Segment(self.get_value("v1"), self.get_value("v3")) s3 = Segment(self.get_value("v2"), self.get_value("v1")) # setting ip1 if len(intersection(s1, points[0])): self.set_intersection_points("ip1", float(points[0][0]), float(points[0][1])) elif len(intersection(s1, points[1])): self.set_intersection_points("ip1", float(points[1][0]), float(points[1][1])) elif len(intersection(s1, points[2])): self.set_intersection_points("ip1", float(points[2][0]), float(points[2][1])) # setting ip2 if len(intersection(s2, points[0])): self.set_intersection_points("ip2", float(points[0][0]), float(points[0][1])) elif len(intersection(s2, points[1])): self.set_intersection_points("ip2", float(points[1][0]), float(points[1][1])) elif len(intersection(s2, points[2])): self.set_intersection_points("ip2", float(points[2][0]), float(points[2][1])) # setting ip3 if len(intersection(s3, points[0])): self.set_intersection_points("ip3", float(points[0][0]), float(points[0][1])) elif len(intersection(s3, points[1])): self.set_intersection_points("ip3", float(points[1][0]), float(points[1][1])) elif len(intersection(s3, points[2])): self.set_intersection_points("ip3", float(points[2][0]), float(points[2][1])) self.Circle.solve() if self.getIPs() == 3 and self.get_value("r") and self.get_value( "circumference") and self.get_value("c"): ip1 = self.get_value("ip1") ip2 = self.get_value("ip2") ip3 = self.get_value("ip3") # Code to find arcs and sectors s = distanceFormula(ip3[0], ip3[1], ip2[0], ip2[1]) angle = lawOfCosinesSSS(s, self.get_value("r"), self.get_value("r")) self.inputs["arc1"] = arcLength(self.get_value("r"), angle) self.inputs["sector1"] = sectorArea(self.get_value("r"), angle) # arc/sector 2 s = distanceFormula(ip1[0], ip1[1], ip3[0], ip3[1]) angle = lawOfCosinesSSS(s, self.get_value("r"), self.get_value("r")) self.inputs["arc2"] = arcLength(self.get_value("r"), angle) self.inputs["sector2"] = sectorArea(self.get_value("r"), angle) # arc/sector 3 s = distanceFormula(ip1[0], ip1[1], ip2[0], ip2[1]) angle = lawOfCosinesSSS(s, self.get_value("r"), self.get_value("r")) self.inputs["arc3"] = arcLength(self.get_value("r"), angle) self.inputs["sector3"] = sectorArea(self.get_value("r"), angle) # Code to find areas from intersections if len(self.Triangle.getMissingVertices()) == 0: # ar1 weirdArea1 = Polygon(ip2, self.get_value("c"), ip3, self.get_value("v1")) self.inputs["ar1"] = round( abs(float(weirdArea1.area)) - self.inputs["sector1"], 2) #ar2 weirdArea2 = Polygon(ip1, self.get_value("c"), ip3, self.get_value("v2")) self.inputs["ar2"] = round( abs(float(weirdArea2.area)) - self.inputs["sector2"], 2) #ar3 weirdArea3 = Polygon(ip1, self.get_value("c"), ip2, self.get_value("v3")) self.inputs["ar3"] = round( abs(float(weirdArea3.area)) - self.inputs["sector3"], 2)
def view_idaho_tiles_by_bbox(self, catId, bbox, output_filename): '''Retrieve and view just the IDAHO chips in a particular bounding box for a catID. Args: catid (str): The source catalog ID from the platform catalog. bbox (list): List of coords: minx(W), miny(S), maxx(E), maxy(N). output_filename (str): a Leaflet Viewer file showing the IDAHO images as tiles. ''' minx, miny, maxx, maxy = bbox #validate bbox values if (minx > maxx): print ('The west value is not less than the east value.') exit if (miny > maxy): print ('The south value is not less than the north value.') exit #create bbox polygon bp1 = Point(minx, miny) bp2 = Point(minx, maxy) bp3 = Point(maxx, maxy) bp4 = Point(maxx, miny) bbox_polygon = Polygon(bp1, bp2, bp3, bp4) #get IDAHO image results: parts idaho_image_results = self.get_images_by_catid(catId) description = self.describe_images(idaho_image_results) tile_count = 0 for catid, images in description.items(): functionstring = '' for partnum, part in images['parts'].items(): num_images = len(list(part.keys())) partname = None if num_images == 1: # there is only one image, use the PAN partname = [p for p in list(part.keys()) if p.upper() == 'PAN'][0] pan_image_id = '' elif num_images == 2: # there are two images in this part, use the multi (or pansharpen) partname = [p for p in list(part.keys()) if p is not 'PAN'][0] pan_image_id = part['PAN']['id'] if not partname: print("Cannot find part for idaho image.") continue bandstr = { 'RGBN': '0,1,2', 'WORLDVIEW_8_BAND': '4,2,1', 'PAN': '0' }.get(partname, '0,1,2') part_boundstr_wkt = part[partname]['boundstr'] part_polygon = geometry.from_wkt(part_boundstr_wkt) bucketname = part[partname]['bucket'] image_id = part[partname]['id'] W, S, E, N = part_polygon.bounds pp1, pp2, pp3, pp4 = Point(W, S), Point(W, N), Point(E, N), Point(E, S) part_bbox_polygon = Polygon(pp1, pp2, pp3, pp4) if (bbox_polygon.intersection(part_bbox_polygon)): functionstring += ("addLayerToMap('%s','%s',%s,%s,%s,%s,'%s');\n" % (bucketname, image_id, W,S,E,N, pan_image_id)) tile_count += 1 print ('There were ' + str(tile_count) + ' IDAHO images found to ' + 'intersect with the provided bounding box.') __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(os.path.realpath('__file__')))) with open(os.path.join(__location__, 'leafletmap_template.html'), 'r') as htmlfile: data=htmlfile.read().decode("utf8") data = data.replace('FUNCTIONSTRING',functionstring) data = data.replace('CENTERLAT',str(S + old_div((N-S),2))) data = data.replace('CENTERLON',str(W + old_div((E-W),2))) data = data.replace('BANDS',bandstr) data = data.replace('TOKEN',self.gbdx_connection.access_token) with codecs.open(output_filename,'w','utf8') as outputfile: print("Saving %s" % output_filename) outputfile.write(data)
def test_ellipse_geom(): p1 = Point(0, 0) p2 = Point(1, 1) p4 = Point(0, 1) e1 = Ellipse(p1, 1, 1) e2 = Ellipse(p2, half, 1) e3 = Ellipse(p1, y1, y1) c1 = Circle(p1, 1) c2 = Circle(p2, 1) c3 = Circle(Point(sqrt(2), sqrt(2)), 1) # Test creation with three points cen, rad = Point(3*half, 2), 5*half assert Circle(Point(0, 0), Point(3, 0), Point(0, 4)) == Circle(cen, rad) raises( GeometryError, lambda: Circle(Point(0, 0), Point(1, 1), Point(2, 2))) raises(ValueError, lambda: Ellipse(None, None, None, 1)) raises(GeometryError, lambda: Circle(Point(0, 0))) # Basic Stuff assert Ellipse(None, 1, 1).center == Point(0, 0) assert e1 == c1 assert e1 != e2 assert p4 in e1 assert p2 not in e2 assert e1.area == pi assert e2.area == pi/2 assert e3.area == pi*y1*abs(y1) assert c1.area == e1.area assert c1.circumference == e1.circumference assert e3.circumference == 2*pi*y1 assert e1.plot_interval() == e2.plot_interval() == [t, -pi, pi] assert e1.plot_interval(x) == e2.plot_interval(x) == [x, -pi, pi] assert Ellipse(None, 1, None, 1).circumference == 2*pi assert c1.minor == 1 assert c1.major == 1 assert c1.hradius == 1 assert c1.vradius == 1 # Private Functions assert hash(c1) == hash(Circle(Point(1, 0), Point(0, 1), Point(0, -1))) assert c1 in e1 assert (Line(p1, p2) in e1) is False assert e1.__cmp__(e1) == 0 assert e1.__cmp__(Point(0, 0)) > 0 # Encloses assert e1.encloses(Segment(Point(-0.5, -0.5), Point(0.5, 0.5))) is True assert e1.encloses(Line(p1, p2)) is False assert e1.encloses(Ray(p1, p2)) is False assert e1.encloses(e1) is False assert e1.encloses( Polygon(Point(-0.5, -0.5), Point(-0.5, 0.5), Point(0.5, 0.5))) is True assert e1.encloses(RegularPolygon(p1, 0.5, 3)) is True assert e1.encloses(RegularPolygon(p1, 5, 3)) is False assert e1.encloses(RegularPolygon(p2, 5, 3)) is False # with generic symbols, the hradius is assumed to contain the major radius M = Symbol('M') m = Symbol('m') c = Ellipse(p1, M, m).circumference _x = c.atoms(Dummy).pop() assert c == 4*M*Integral( sqrt((1 - _x**2*(M**2 - m**2)/M**2)/(1 - _x**2)), (_x, 0, 1)) assert e2.arbitrary_point() in e2 # Foci f1, f2 = Point(sqrt(12), 0), Point(-sqrt(12), 0) ef = Ellipse(Point(0, 0), 4, 2) assert ef.foci in [(f1, f2), (f2, f1)] # Tangents v = sqrt(2) / 2 p1_1 = Point(v, v) p1_2 = p2 + Point(half, 0) p1_3 = p2 + Point(0, 1) assert e1.tangent_lines(p4) == c1.tangent_lines(p4) assert e2.tangent_lines(p1_2) == [Line(Point(3/2, 1), Point(3/2, 1/2))] assert e2.tangent_lines(p1_3) == [Line(Point(1, 2), Point(5/4, 2))] assert c1.tangent_lines(p1_1) != [Line(p1_1, Point(0, sqrt(2)))] assert c1.tangent_lines(p1) == [] assert e2.is_tangent(Line(p1_2, p2 + Point(half, 1))) assert e2.is_tangent(Line(p1_3, p2 + Point(half, 1))) assert c1.is_tangent(Line(p1_1, Point(0, sqrt(2)))) assert e1.is_tangent(Line(Point(0, 0), Point(1, 1))) is False assert c1.is_tangent(e1) is False assert c1.is_tangent(Ellipse(Point(2, 0), 1, 1)) is True assert c1.is_tangent( Polygon(Point(1, 1), Point(1, -1), Point(2, 0))) is True assert c1.is_tangent( Polygon(Point(1, 1), Point(1, 0), Point(2, 0))) is False assert Circle(Point(5, 5), 3).is_tangent(Circle(Point(0, 5), 1)) is False assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(77/25, 132/25)), Line(Point(0, 0), Point(33/5, 22/5))] assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(3, 4)) == \ [Line(Point(3, 4), Point(4, 4)), Line(Point(3, 4), Point(3, 5))] assert Circle(Point(5, 5), 2).tangent_lines(Point(3, 3)) == \ [Line(Point(3, 3), Point(4, 3)), Line(Point(3, 3), Point(3, 4))] assert Circle(Point(5, 5), 2).tangent_lines(Point(5 - 2*sqrt(2), 5)) == \ [Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 - sqrt(2))), Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 + sqrt(2))), ] e = Ellipse(Point(0, 0), 2, 1) assert e.normal_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(0, 1)), Line(Point(0, 0), Point(1, 0))] assert e.normal_lines(Point(1, 0)) == \ [Line(Point(0, 0), Point(1, 0))] assert e.normal_lines((0, 1)) == \ [Line(Point(0, 0), Point(0, 1))] assert e.normal_lines(Point(1, 1), 2) == [ Line(Point(-51/26, -1/5), Point(-25/26, 17/83)), Line(Point(28/29, -7/8), Point(57/29, -9/2))] # test the failure of Poly.intervals and checks a point on the boundary p = Point(sqrt(3), S.Half) assert p in e assert e.normal_lines(p, 2) == [ Line(Point(-341/171, -1/13), Point(-170/171, 5/64)), Line(Point(26/15, -1/2), Point(41/15, -43/26))] # be sure to use the slope that isn't undefined on boundary e = Ellipse((0, 0), 2, 2*sqrt(3)/3) assert e.normal_lines((1, 1), 2) == [ Line(Point(-64/33, -20/71), Point(-31/33, 2/13)), Line(Point(1, -1), Point(2, -4))] # general ellipse fails except under certain conditions e = Ellipse((0, 0), x, 1) assert e.normal_lines((x + 1, 0)) == [Line(Point(0, 0), Point(1, 0))] raises(NotImplementedError, lambda: e.normal_lines((x + 1, 1))) # Properties major = 3 minor = 1 e4 = Ellipse(p2, minor, major) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major*(1 - ecc) assert e4.apoapsis == major*(1 + ecc) # independent of orientation e4 = Ellipse(p2, major, minor) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major*(1 - ecc) assert e4.apoapsis == major*(1 + ecc) # Intersection l1 = Line(Point(1, -5), Point(1, 5)) l2 = Line(Point(-5, -1), Point(5, -1)) l3 = Line(Point(-1, -1), Point(1, 1)) l4 = Line(Point(-10, 0), Point(0, 10)) pts_c1_l3 = [Point(sqrt(2)/2, sqrt(2)/2), Point(-sqrt(2)/2, -sqrt(2)/2)] assert intersection(e2, l4) == [] assert intersection(c1, Point(1, 0)) == [Point(1, 0)] assert intersection(c1, l1) == [Point(1, 0)] assert intersection(c1, l2) == [Point(0, -1)] assert intersection(c1, l3) in [pts_c1_l3, [pts_c1_l3[1], pts_c1_l3[0]]] assert intersection(c1, c2) == [Point(0, 1), Point(1, 0)] assert intersection(c1, c3) == [Point(sqrt(2)/2, sqrt(2)/2)] assert e1.intersection(l1) == [Point(1, 0)] assert e2.intersection(l4) == [] assert e1.intersection(Circle(Point(0, 2), 1)) == [Point(0, 1)] assert e1.intersection(Circle(Point(5, 0), 1)) == [] assert e1.intersection(Ellipse(Point(2, 0), 1, 1)) == [Point(1, 0)] assert e1.intersection(Ellipse(Point(5, 0), 1, 1,)) == [] assert e1.intersection(Point(2, 0)) == [] assert e1.intersection(e1) == e1 # some special case intersections csmall = Circle(p1, 3) cbig = Circle(p1, 5) cout = Circle(Point(5, 5), 1) # one circle inside of another assert csmall.intersection(cbig) == [] # separate circles assert csmall.intersection(cout) == [] # coincident circles assert csmall.intersection(csmall) == csmall v = sqrt(2) t1 = Triangle(Point(0, v), Point(0, -v), Point(v, 0)) points = intersection(t1, c1) assert len(points) == 4 assert Point(0, 1) in points assert Point(0, -1) in points assert Point(v/2, v/2) in points assert Point(v/2, -v/2) in points circ = Circle(Point(0, 0), 5) elip = Ellipse(Point(0, 0), 5, 20) assert intersection(circ, elip) in \ [[Point(5, 0), Point(-5, 0)], [Point(-5, 0), Point(5, 0)]] assert elip.tangent_lines(Point(0, 0)) == [] elip = Ellipse(Point(0, 0), 3, 2) assert elip.tangent_lines(Point(3, 0)) == \ [Line(Point(3, 0), Point(3, -12))] e1 = Ellipse(Point(0, 0), 5, 10) e2 = Ellipse(Point(2, 1), 4, 8) a = 53/17 c = 2*sqrt(3991)/17 ans = [Point(a - c/8, a/2 + c), Point(a + c/8, a/2 - c)] assert e1.intersection(e2) == ans e2 = Ellipse(Point(x, y), 4, 8) c = sqrt(3991) ans = [Point(-c/68 + a, 2*c/17 + a/2), Point(c/68 + a, -2*c/17 + a/2)] assert [p.subs({x: 2, y:1}) for p in e1.intersection(e2)] == ans # Combinations of above assert e3.is_tangent(e3.tangent_lines(p1 + Point(y1, 0))[0]) e = Ellipse((1, 2), 3, 2) assert e.tangent_lines(Point(10, 0)) == \ [Line(Point(10, 0), Point(1, 0)), Line(Point(10, 0), Point(14/5, 18/5))] # encloses_point e = Ellipse((0, 0), 1, 2) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point( e.center + Point(e.hradius + Rational(1, 10), 0)) is False e = Ellipse((0, 0), 2, 1) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point( e.center + Point(e.hradius + Rational(1, 10), 0)) is False assert c1.encloses_point(Point(1, 0)) is False assert c1.encloses_point(Point(0.3, 0.4)) is True assert e.scale(2, 3) == Ellipse((0, 0), 4, 3) assert e.scale(3, 6) == Ellipse((0, 0), 6, 6) assert e.rotate(pi) == e assert e.rotate(pi, (1, 2)) == Ellipse(Point(2, 4), 2, 1) raises(NotImplementedError, lambda: e.rotate(pi/3)) # transformations c = Circle((1, 1), 2) assert c.scale(-1) == Circle((-1, 1), 2) assert c.scale(y=-1) == Circle((1, -1), 2) assert c.scale(2) == Ellipse((2, 1), 4, 2)
def test_polygon(): x = Symbol('x', real=True) y = Symbol('y', real=True) x1 = Symbol('x1', real=True) half = Rational(1, 2) a, b, c = Point(0, 0), Point(2, 0), Point(3, 3) t = Triangle(a, b, c) assert Polygon(a, Point(1, 0), b, c) == t assert Polygon(Point(1, 0), b, c, a) == t assert Polygon(b, c, a, Point(1, 0)) == t # 2 "remove folded" tests assert Polygon(a, Point(3, 0), b, c) == t assert Polygon(a, b, Point(3, -1), b, c) == t raises(GeometryError, lambda: Polygon((0, 0), (1, 0), (0, 1), (1, 1))) # remove multiple collinear points assert Polygon(Point(-4, 15), Point(-11, 15), Point(-15, 15), Point(-15, 33/5), Point(-15, -87/10), Point(-15, -15), Point(-42/5, -15), Point(-2, -15), Point(7, -15), Point(15, -15), Point(15, -3), Point(15, 10), Point(15, 15)) == \ Polygon(Point(-15,-15), Point(15,-15), Point(15,15), Point(-15,15)) p1 = Polygon( Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon( Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon( Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon( Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) p5 = Polygon( Point(0, 0), Point(4, 4), Point(0, 4)) p6 = Polygon( Point(-11, 1), Point(-9, 6.6), Point(-4, -3), Point(-8.4, -8.7)) r = Ray(Point(-9,6.6), Point(-9,5.5)) # # General polygon # assert p1 == p2 assert len(p1.args) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2*sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() # ensure convex for both CW and CCW point specification assert p3.is_convex() assert p4.is_convex() dict5 = p5.angles assert dict5[Point(0, 0)] == pi / 4 assert dict5[Point(0, 4)] == pi / 2 assert p5.encloses_point(Point(x, y)) is None assert p5.encloses_point(Point(1, 3)) assert p5.encloses_point(Point(0, 0)) is False assert p5.encloses_point(Point(4, 0)) is False assert p1.encloses(Circle(Point(2.5,2.5),5)) is False assert p1.encloses(Ellipse(Point(2.5,2),5,6)) is False p5.plot_interval('x') == [x, 0, 1] assert p5.distance( Polygon(Point(10, 10), Point(14, 14), Point(10, 14))) == 6 * sqrt(2) assert p5.distance( Polygon(Point(1, 8), Point(5, 8), Point(8, 12), Point(1, 12))) == 4 warnings.filterwarnings( "error", message="Polygons may intersect producing erroneous output") raises(UserWarning, lambda: Polygon(Point(0, 0), Point(1, 0), Point(1, 1)).distance( Polygon(Point(0, 0), Point(0, 1), Point(1, 1)))) warnings.filterwarnings( "ignore", message="Polygons may intersect producing erroneous output") assert hash(p5) == hash(Polygon(Point(0, 0), Point(4, 4), Point(0, 4))) assert p5 == Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) assert Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) in p5 assert p5 != Point(0, 4) assert Point(0, 1) in p5 assert p5.arbitrary_point('t').subs(Symbol('t', real=True), 0) == \ Point(0, 0) raises(ValueError, lambda: Polygon( Point(x, 0), Point(0, y), Point(x, y)).arbitrary_point('x')) assert p6.intersection(r) == [Point(-9, 33/5), Point(-9, -84/13)] # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), Point(0, 1), Point(1, 1))) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), 1, 2)) raises(ValueError, lambda: RegularPolygon(Point(0, 0), 1, 2.5)) assert p1 != p2 assert p1.interior_angle == 3*pi/5 assert p1.exterior_angle == 2*pi/5 assert p2.apothem == 5*cos(pi/5) assert p2.circumcenter == p1.circumcenter == Point(0, 0) assert p1.circumradius == p1.radius == 10 assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p2.inradius == p2.apothem == (5 * (1 + sqrt(5)) / 4) p2.spin(pi / 10) dict1 = p2.angles assert dict1[Point(0, 5)] == 3 * pi / 5 assert p1.is_convex() assert p1.rotation == 0 assert p1.encloses_point(Point(0, 0)) assert p1.encloses_point(Point(11, 0)) is False assert p2.encloses_point(Point(0, 4.9)) p1.spin(pi/3) assert p1.rotation == pi/3 assert p1.vertices[0] == Point(5, 5*sqrt(3)) for var in p1.args: if isinstance(var, Point): assert var == Point(0, 0) else: assert var == 5 or var == 10 or var == pi / 3 assert p1 != Point(0, 0) assert p1 != p5 # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi/3) == RegularPolygon(Point(0, 0), 10, 5, 2*pi/3) assert p1 == p1_old assert p1.area == (-250*sqrt(5) + 1250)/(4*tan(pi/5)) assert p1.length == 20*sqrt(-sqrt(5)/8 + 5/8) assert p1.scale(2, 2) == \ RegularPolygon(p1.center, p1.radius*2, p1._n, p1.rotation) assert RegularPolygon((0, 0), 1, 4).scale(2, 3) == \ Polygon(Point(2, 0), Point(0, 3), Point(-2, 0), Point(0, -3)) assert repr(p1) == str(p1) # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides assert Triangle(p1, p2, p1) == Polygon(p1, p2, p1) == Segment(p1, p2) raises(GeometryError, lambda: Triangle(Point(0, 0))) # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2*2, p2*3) == Segment(p2, p2*3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() is False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf()/2) assert t1.is_equilateral() is False assert t2.is_equilateral() assert t3.is_equilateral() is False assert are_similar(t1, t2) is False assert are_similar(t1, t3) assert are_similar(t2, t3) is False assert t1.is_similar(Point(0, 0)) is False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125*sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == t1.incircle.radius == 5 - 5*sqrt(2)/2 assert t2.inradius == t2.incircle.radius == 5*sqrt(3)/6 assert t3.inradius == t3.incircle.radius == x1**2/((2 + sqrt(2))*Abs(x1)) # Circumcircle assert t1.circumcircle.center == Point(2.5, 2.5) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1/2, x1/2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] assert t1.medial == Triangle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) # Nine-point circle assert t1.nine_point_circle == Circle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) assert t1.nine_point_circle == Circle(Point(0, 0), Point(0, 2.5), Point(2.5, 2.5)) # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] assert t1.orthocenter == p1 t = S('''Triangle( Point(100080156402737/5000000000000, 79782624633431/500000000000), Point(39223884078253/2000000000000, 156345163124289/1000000000000), Point(31241359188437/1250000000000, 338338270939941/1000000000000000))''') assert t.orthocenter == S('''Point(-780660869050599840216997''' '''79471538701955848721853/80368430960602242240789074233100000000000000,''' '''20151573611150265741278060334545897615974257/16073686192120448448157''' '''8148466200000000000)''') # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon( Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5)/4), Point(1, Rational(5)/4), Point(1, Rational(9)/4), Point(0, Rational(9)/4)) p3 = Polygon( Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon( Point(1, 1), Point(Rational(6)/5, 1), Point(1, Rational(6)/5)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3)/4 assert p3.distance(pt2) == sqrt(2)/2 '''Polygon to Polygon''' # p1.distance(p2) emits a warning # First, test the warning warnings.filterwarnings("error", message="Polygons may intersect producing erroneous output") raises(UserWarning, lambda: p1.distance(p2)) # now test the actual output warnings.filterwarnings("ignore", message="Polygons may intersect producing erroneous output") assert p1.distance(p2) == half/2 assert p1.distance(p3) == sqrt(2)/2 assert p3.distance(p4) == (sqrt(2)/2 - sqrt(Rational(2)/25)/2)
def test_polygon(): x = Symbol('x', real=True) y = Symbol('y', real=True) q = Symbol('q', real=True) u = Symbol('u', real=True) v = Symbol('v', real=True) w = Symbol('w', real=True) x1 = Symbol('x1', real=True) half = Rational(1, 2) a, b, c = Point(0, 0), Point(2, 0), Point(3, 3) t = Triangle(a, b, c) assert Polygon(a, Point(1, 0), b, c) == t assert Polygon(Point(1, 0), b, c, a) == t assert Polygon(b, c, a, Point(1, 0)) == t # 2 "remove folded" tests assert Polygon(a, Point(3, 0), b, c) == t assert Polygon(a, b, Point(3, -1), b, c) == t # remove multiple collinear points assert Polygon(Point(-4, 15), Point(-11, 15), Point(-15, 15), Point(-15, 33/5), Point(-15, -87/10), Point(-15, -15), Point(-42/5, -15), Point(-2, -15), Point(7, -15), Point(15, -15), Point(15, -3), Point(15, 10), Point(15, 15)) == \ Polygon(Point(-15,-15), Point(15,-15), Point(15,15), Point(-15,15)) p1 = Polygon( Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon( Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon( Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon( Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) p5 = Polygon( Point(0, 0), Point(4, 4), Point(0, 4)) p6 = Polygon( Point(-11, 1), Point(-9, 6.6), Point(-4, -3), Point(-8.4, -8.7)) p7 = Polygon( Point(x, y), Point(q, u), Point(v, w)) p8 = Polygon( Point(x, y), Point(v, w), Point(q, u)) p9 = Polygon( Point(0, 0), Point(4, 4), Point(3, 0), Point(5, 2)) p10 = Polygon( Point(0, 2), Point(2, 2), Point(0, 0), Point(2, 0)) p11 = Polygon(Point(0, 0), 1, n=3) r = Ray(Point(-9,6.6), Point(-9,5.5)) # # General polygon # assert p1 == p2 assert len(p1.args) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2*sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert Polygon((-1, 1), (2, -1), (2, 1), (-1, -1), (3, 0) ).is_convex() is False # ensure convex for both CW and CCW point specification assert p3.is_convex() assert p4.is_convex() dict5 = p5.angles assert dict5[Point(0, 0)] == pi / 4 assert dict5[Point(0, 4)] == pi / 2 assert p5.encloses_point(Point(x, y)) is None assert p5.encloses_point(Point(1, 3)) assert p5.encloses_point(Point(0, 0)) is False assert p5.encloses_point(Point(4, 0)) is False assert p1.encloses(Circle(Point(2.5,2.5),5)) is False assert p1.encloses(Ellipse(Point(2.5,2),5,6)) is False p5.plot_interval('x') == [x, 0, 1] assert p5.distance( Polygon(Point(10, 10), Point(14, 14), Point(10, 14))) == 6 * sqrt(2) assert p5.distance( Polygon(Point(1, 8), Point(5, 8), Point(8, 12), Point(1, 12))) == 4 with warns(UserWarning, \ match="Polygons may intersect producing erroneous output"): Polygon(Point(0, 0), Point(1, 0), Point(1, 1)).distance( Polygon(Point(0, 0), Point(0, 1), Point(1, 1))) assert hash(p5) == hash(Polygon(Point(0, 0), Point(4, 4), Point(0, 4))) assert hash(p1) == hash(p2) assert hash(p7) == hash(p8) assert hash(p3) != hash(p9) assert p5 == Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) assert Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) in p5 assert p5 != Point(0, 4) assert Point(0, 1) in p5 assert p5.arbitrary_point('t').subs(Symbol('t', real=True), 0) == \ Point(0, 0) raises(ValueError, lambda: Polygon( Point(x, 0), Point(0, y), Point(x, y)).arbitrary_point('x')) assert p6.intersection(r) == [Point(-9, -S(84)/13), Point(-9, S(33)/5)] assert p10.area == 0 assert p11 == RegularPolygon(Point(0, 0), 1, 3, 0) assert p11.vertices[0] == Point(1, 0) assert p11.args[0] == Point(0, 0) p11.spin(pi/2) assert p11.vertices[0] == Point(0, 1) # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), Point(0, 1), Point(1, 1))) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), 1, 2)) raises(ValueError, lambda: RegularPolygon(Point(0, 0), 1, 2.5)) assert p1 != p2 assert p1.interior_angle == 3*pi/5 assert p1.exterior_angle == 2*pi/5 assert p2.apothem == 5*cos(pi/5) assert p2.circumcenter == p1.circumcenter == Point(0, 0) assert p1.circumradius == p1.radius == 10 assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p2.inradius == p2.apothem == (5 * (1 + sqrt(5)) / 4) p2.spin(pi / 10) dict1 = p2.angles assert dict1[Point(0, 5)] == 3 * pi / 5 assert p1.is_convex() assert p1.rotation == 0 assert p1.encloses_point(Point(0, 0)) assert p1.encloses_point(Point(11, 0)) is False assert p2.encloses_point(Point(0, 4.9)) p1.spin(pi/3) assert p1.rotation == pi/3 assert p1.vertices[0] == Point(5, 5*sqrt(3)) for var in p1.args: if isinstance(var, Point): assert var == Point(0, 0) else: assert var == 5 or var == 10 or var == pi / 3 assert p1 != Point(0, 0) assert p1 != p5 # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi/3) == RegularPolygon(Point(0, 0), 10, 5, 2*pi/3) assert p1 == p1_old assert p1.area == (-250*sqrt(5) + 1250)/(4*tan(pi/5)) assert p1.length == 20*sqrt(-sqrt(5)/8 + S(5)/8) assert p1.scale(2, 2) == \ RegularPolygon(p1.center, p1.radius*2, p1._n, p1.rotation) assert RegularPolygon((0, 0), 1, 4).scale(2, 3) == \ Polygon(Point(2, 0), Point(0, 3), Point(-2, 0), Point(0, -3)) assert repr(p1) == str(p1) # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides assert Triangle(p1, p2, p1) == Polygon(p1, p2, p1) == Segment(p1, p2) raises(GeometryError, lambda: Triangle(Point(0, 0))) # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2*2, p2*3) == Segment(p2, p2*3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() is False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf()/2) assert t1.is_equilateral() is False assert t2.is_equilateral() assert t3.is_equilateral() is False assert are_similar(t1, t2) is False assert are_similar(t1, t3) assert are_similar(t2, t3) is False assert t1.is_similar(Point(0, 0)) is False assert t1.is_similar(t2) is False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment( p1, Point(Rational(5, 2), Rational(5, 2))) assert t2.bisectors()[p2] == Segment( Point(5, 0), Point(Rational(5, 4), 5*sqrt(3)/4)) p4 = Point(0, x1) assert t3.bisectors()[p4] == Segment(p4, Point(x1*(sqrt(2) - 1), 0)) ic = (250 - 125*sqrt(2))/50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == t1.incircle.radius == 5 - 5*sqrt(2)/2 assert t2.inradius == t2.incircle.radius == 5*sqrt(3)/6 assert t3.inradius == t3.incircle.radius == x1**2/((2 + sqrt(2))*Abs(x1)) # Exradius assert t1.exradii[t1.sides[2]] == 5*sqrt(2)/2 # Circumcircle assert t1.circumcircle.center == Point(2.5, 2.5) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1/2, x1/2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] assert t1.medial == Triangle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) # Nine-point circle assert t1.nine_point_circle == Circle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) assert t1.nine_point_circle == Circle(Point(0, 0), Point(0, 2.5), Point(2.5, 2.5)) # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2].equals(s1[0]) assert altitudes[p3] == s1[2] assert t1.orthocenter == p1 t = S('''Triangle( Point(100080156402737/5000000000000, 79782624633431/500000000000), Point(39223884078253/2000000000000, 156345163124289/1000000000000), Point(31241359188437/1250000000000, 338338270939941/1000000000000000))''') assert t.orthocenter == S('''Point(-780660869050599840216997''' '''79471538701955848721853/80368430960602242240789074233100000000000000,''' '''20151573611150265741278060334545897615974257/16073686192120448448157''' '''8148466200000000000)''') # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon( Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5)/4), Point(1, Rational(5)/4), Point(1, Rational(9)/4), Point(0, Rational(9)/4)) p3 = Polygon( Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon( Point(1, 1), Point(Rational(6)/5, 1), Point(1, Rational(6)/5)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3)/4 assert p3.distance(pt2) == sqrt(2)/2 '''Polygon to Polygon''' # p1.distance(p2) emits a warning with warns(UserWarning, \ match="Polygons may intersect producing erroneous output"): assert p1.distance(p2) == half/2 assert p1.distance(p3) == sqrt(2)/2 # p3.distance(p4) emits a warning with warns(UserWarning, \ match="Polygons may intersect producing erroneous output"): assert p3.distance(p4) == (sqrt(2)/2 - sqrt(Rational(2)/25)/2)
def test_cut_section(): # concave polygon p = Polygon((-1, -1), (1, Rational(5, 2)), (2, 1), (3, Rational(5, 2)), (4, 2), (5, 3), (-1, 3)) l = Line((0, 0), (Rational(9, 2), 3)) p1 = p.cut_section(l)[0] p2 = p.cut_section(l)[1] assert p1 == Polygon( Point2D(Rational(-9, 13), Rational(-6, 13)), Point2D(1, Rational(5, 2)), Point2D(Rational(24, 13), Rational(16, 13)), Point2D(Rational(12, 5), Rational(8, 5)), Point2D(3, Rational(5, 2)), Point2D(Rational(24, 7), Rational(16, 7)), Point2D(Rational(9, 2), 3), Point2D(-1, 3), Point2D(-1, Rational(-2, 3))) assert p2 == Polygon(Point2D(-1, -1), Point2D(Rational(-9, 13), Rational(-6, 13)), Point2D(Rational(24, 13), Rational(16, 13)), Point2D(2, 1), Point2D(Rational(12, 5), Rational(8, 5)), Point2D(Rational(24, 7), Rational(16, 7)), Point2D(4, 2), Point2D(5, 3), Point2D(Rational(9, 2), 3), Point2D(-1, Rational(-2, 3))) # convex polygon p = RegularPolygon(Point2D(0, 0), 6, 6) s = p.cut_section(Line((0, 0), slope=1)) assert s[0] == Polygon(Point2D(-3*sqrt(3) + 9, -3*sqrt(3) + 9), Point2D(3, 3*sqrt(3)), Point2D(-3, 3*sqrt(3)), Point2D(-6, 0), Point2D(-9 + 3*sqrt(3), -9 + 3*sqrt(3))) assert s[1] == Polygon(Point2D(6, 0), Point2D(-3*sqrt(3) + 9, -3*sqrt(3) + 9), Point2D(-9 + 3*sqrt(3), -9 + 3*sqrt(3)), Point2D(-3, -3*sqrt(3)), Point2D(3, -3*sqrt(3))) # case where line does not intersects but coincides with the edge of polygon a, b = 20, 10 t1, t2, t3, t4 = [(0, b), (0, 0), (a, 0), (a, b)] p = Polygon(t1, t2, t3, t4) p1, p2 = p.cut_section(Line((0, b), slope=0)) assert p1 == None assert p2 == Polygon(Point2D(0, 10), Point2D(0, 0), Point2D(20, 0), Point2D(20, 10)) p3, p4 = p.cut_section(Line((0, 0), slope=0)) assert p3 == Polygon(Point2D(0, 10), Point2D(0, 0), Point2D(20, 0), Point2D(20, 10)) assert p4 == None # case where the line does not intersect with a polygon at all raises(ValueError, lambda: p.cut_section(Line((0, a), slope=0)))
def test_transform(): pts = [Point(0, 0), Point(S.Half, Rational(1, 4)), Point(1, 1)] pts_out = [Point(-4, -10), Point(-3, Rational(-37, 4)), Point(-2, -7)] assert Triangle(*pts).scale(2, 3, (4, 5)) == Triangle(*pts_out) assert RegularPolygon((0, 0), 1, 4).scale(2, 3, (4, 5)) == \ Polygon(Point(-2, -10), Point(-4, -7), Point(-6, -10), Point(-4, -13))
def test_polygon(): t = Triangle(Point(0, 0), Point(2, 0), Point(3, 3)) assert Polygon(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 3)) == t assert Polygon(Point(1, 0), Point(2, 0), Point(3, 3), Point(0, 0)) == t assert Polygon(Point(2, 0), Point(3, 3), Point(0, 0), Point(1, 0)) == t p1 = Polygon( Point(0, 0), Point(3,-1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon( Point(6, 0), Point(3,-1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon( Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon( Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) p5 = Polygon( Point(0, 0), Point(4, 4), Point(0, 4)) # # General polygon # assert p1 == p2 assert len(p1.args) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5+2*sqrt(10)+sqrt(29)+sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex() # ensure convex for both CW and CCW point specification dict5 = p5.angles assert dict5[Point(0, 0)] == pi / 4 assert dict5[Point(0, 4)] == pi / 2 assert p5.encloses_point(Point(x, y)) == None assert p5.encloses_point(Point(1, 3)) assert p5.encloses_point(Point(0, 0)) == False assert p5.encloses_point(Point(4, 0)) == False p5.plot_interval('x') == [x, 0, 1] assert p5.distance(Polygon(Point(10, 10), Point(14, 14), Point(10, 14))) == 6 * sqrt(2) assert p5.distance(Polygon(Point(1, 8), Point(5, 8), Point(8, 12), Point(1, 12))) == 4 raises(UserWarning, 'Polygon(Point(0, 0), Point(1, 0), Point(1,1)).distance(Polygon(Point(0, 0), Point(0, 1), Point(1, 1)))') assert hash(p5) == hash(Polygon(Point(0, 0), Point(4, 4), Point(0, 4))) assert p5 == Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) assert Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) in p5 assert p5 != Point(0, 4) assert Point(0, 1) in p5 assert p5.arbitrary_point('t').subs(Symbol('t', real=True), 0) == Point(0, 0) raises(ValueError, "Polygon(Point(x, 0), Point(0, y), Point(x, y)).arbitrary_point('x')") # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) raises(GeometryError, 'RegularPolygon(Point(0, 0), Point(0, 1), Point(1, 1))') raises(GeometryError, 'RegularPolygon(Point(0, 0), 1, 2)') raises(ValueError, 'RegularPolygon(Point(0, 0), 1, 2.5)') assert p1 != p2 assert p1.interior_angle == 3*pi/5 assert p1.exterior_angle == 2*pi/5 assert p2.apothem == 5*cos(pi/5) assert p2.circumcenter == p1.circumcenter == Point(0, 0) assert p1.circumradius == p1.radius == 10 assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p2.inradius == p2.apothem == (5 * (1 + sqrt(5)) / 4) p2.spin(pi / 10) dict1 = p2.angles assert dict1[Point(0, 5)] == 3 * pi / 5 assert p1.is_convex() assert p1.rotation == 0 assert p1.encloses_point(Point(0, 0)) assert p1.encloses_point(Point(11, 0)) == False assert p2.encloses_point(Point(0, 4.9)) p1.spin(pi/3) assert p1.rotation == pi/3 assert p1.vertices[0] == Point(5, 5*sqrt(3)) for var in p1.args: if isinstance(var, Point): assert var == Point(0, 0) else: assert var == 5 or var == 10 or var == pi / 3 assert p1 != Point(0, 0) assert p1 != p5 # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi/3) == RegularPolygon(Point(0, 0), 10, 5, 2*pi/3) assert p1 == p1_old assert `p1` == str(p1) # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5,2), sqrt(Rational(75,4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides assert Triangle(p1, p2, p1) == Polygon(p1, p2, p1) == Segment(p1, p2) raises(GeometryError, 'Triangle(Point(0, 0))') # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2*2, p2*3) == Segment(p2, p2*3) assert t1.area == Rational(25,2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf()/2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False assert t1.is_similar(Point(0, 0)) == False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) ic = (250 - 125*sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == t1.incircle.radius == 5 - 5*sqrt(2)/2 assert t2.inradius == t2.incircle.radius == 5*sqrt(3)/6 assert t3.inradius == t3.incircle.radius == x1**2/((2 + sqrt(2))*Abs(x1)) # Circumcircle assert t1.circumcircle.center == Point(2.5, 2.5) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5,3), Rational(5,3)) assert m[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) assert t3.medians[p1] == Segment(p1, Point(x1/2, x1/2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] assert t1.medial == Triangle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] assert t1.orthocenter == p1 # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon( Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5)/4), Point(1, Rational(5)/4), Point(1, Rational(9)/4), Point(0, Rational(9)/4)) p3 = Polygon( Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon( Point(1, 1), Point(Rational(6)/5, 1), Point(1, Rational(6)/5)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3)/4 assert p3.distance(pt2) == sqrt(2)/2
def test_type_of_triangle(): # Isoceles triangle p1 = Polygon(Point(0, 0), Point(5, 0), Point(2, 4)) assert p1.is_isosceles() == True assert p1.is_scalene() == False assert p1.is_equilateral() == False # Scalene triangle p2 = Polygon (Point(0, 0), Point(0, 2), Point(4, 0)) assert p2.is_isosceles() == False assert p2.is_scalene() == True assert p2.is_equilateral() == False # Equilateral triagle p3 = Polygon(Point(0, 0), Point(6, 0), Point(3, sqrt(27))) assert p3.is_isosceles() == True assert p3.is_scalene() == False assert p3.is_equilateral() == True
def test_polygon(): t = Triangle(Point(0, 0), Point(2, 0), Point(3, 3)) assert Polygon(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 3)) == t assert Polygon(Point(1, 0), Point(2, 0), Point(3, 3), Point(0, 0)) == t assert Polygon(Point(2, 0), Point(3, 3), Point(0, 0), Point(1, 0)) == t p1 = Polygon(Point(0, 0), Point(3, -1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon(Point(6, 0), Point(3, -1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon(Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon(Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) p5 = Polygon(Point(0, 0), Point(4, 4), Point(0, 4)) # # General polygon # assert p1 == p2 assert len(p1.args) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5 + 2 * sqrt(10) + sqrt(29) + sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex() # ensure convex for both CW and CCW point specification dict5 = p5.angles assert dict5[Point(0, 0)] == pi / 4 assert dict5[Point(0, 4)] == pi / 2 assert p5.encloses_point(Point(x, y)) == None assert p5.encloses_point(Point(1, 3)) assert p5.encloses_point(Point(0, 0)) == False assert p5.encloses_point(Point(4, 0)) == False p5.plot_interval("x") == [x, 0, 1] assert p5.distance(Polygon(Point(10, 10), Point(14, 14), Point(10, 14))) == 6 * sqrt(2) assert p5.distance(Polygon(Point(1, 8), Point(5, 8), Point(8, 12), Point(1, 12))) == 4 raises( UserWarning, lambda: Polygon(Point(0, 0), Point(1, 0), Point(1, 1)).distance(Polygon(Point(0, 0), Point(0, 1), Point(1, 1))), ) assert hash(p5) == hash(Polygon(Point(0, 0), Point(4, 4), Point(0, 4))) assert p5 == Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) assert Polygon(Point(4, 4), Point(0, 4), Point(0, 0)) in p5 assert p5 != Point(0, 4) assert Point(0, 1) in p5 assert p5.arbitrary_point("t").subs(Symbol("t", real=True), 0) == Point(0, 0) raises(ValueError, lambda: Polygon(Point(x, 0), Point(0, y), Point(x, y)).arbitrary_point("x")) # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), Point(0, 1), Point(1, 1))) raises(GeometryError, lambda: RegularPolygon(Point(0, 0), 1, 2)) raises(ValueError, lambda: RegularPolygon(Point(0, 0), 1, 2.5)) assert p1 != p2 assert p1.interior_angle == 3 * pi / 5 assert p1.exterior_angle == 2 * pi / 5 assert p2.apothem == 5 * cos(pi / 5) assert p2.circumcenter == p1.circumcenter == Point(0, 0) assert p1.circumradius == p1.radius == 10 assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p2.inradius == p2.apothem == (5 * (1 + sqrt(5)) / 4) p2.spin(pi / 10) dict1 = p2.angles assert dict1[Point(0, 5)] == 3 * pi / 5 assert p1.is_convex() assert p1.rotation == 0 assert p1.encloses_point(Point(0, 0)) assert p1.encloses_point(Point(11, 0)) == False assert p2.encloses_point(Point(0, 4.9)) p1.spin(pi / 3) assert p1.rotation == pi / 3 assert p1.vertices[0] == Point(5, 5 * sqrt(3)) for var in p1.args: if isinstance(var, Point): assert var == Point(0, 0) else: assert var == 5 or var == 10 or var == pi / 3 assert p1 != Point(0, 0) assert p1 != p5 # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi / 3) == RegularPolygon(Point(0, 0), 10, 5, 2 * pi / 3) assert p1 == p1_old assert p1.area == (-250 * sqrt(5) + 1250) / (4 * tan(pi / 5)) assert p1.length == 20 * sqrt(-sqrt(5) / 8 + S(5) / 8) assert p1.scale(2, 2) == RegularPolygon(p1.center, p1.radius * 2, p1._n, p1.rotation) assert RegularPolygon((0, 0), 1, 4).scale(2, 3) == Polygon(Point(2, 0), Point(0, 3), Point(-2, 0), Point(0, -3)) assert ` p1 ` == str(p1) # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5, 2), sqrt(Rational(75, 4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides assert Triangle(p1, p2, p1) == Polygon(p1, p2, p1) == Segment(p1, p2) raises(GeometryError, lambda: Triangle(Point(0, 0))) # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2 * 2, p2 * 3) == Segment(p2, p2 * 3) assert t1.area == Rational(25, 2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf() / 2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False assert t1.is_similar(Point(0, 0)) == False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) ic = (250 - 125 * sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == t1.incircle.radius == 5 - 5 * sqrt(2) / 2 assert t2.inradius == t2.incircle.radius == 5 * sqrt(3) / 6 assert t3.inradius == t3.incircle.radius == x1 ** 2 / ((2 + sqrt(2)) * Abs(x1)) # Circumcircle assert t1.circumcircle.center == Point(2.5, 2.5) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5, 3), Rational(5, 3)) assert m[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert t3.medians[p1] == Segment(p1, Point(x1 / 2, x1 / 2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] assert t1.medial == Triangle(Point(2.5, 0), Point(0, 2.5), Point(2.5, 2.5)) # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5, 2), Rational(5, 2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] assert t1.orthocenter == p1 t = S( """Triangle( Point(100080156402737/5000000000000, 79782624633431/500000000000), Point(39223884078253/2000000000000, 156345163124289/1000000000000), Point(31241359188437/1250000000000, 338338270939941/1000000000000000))""" ) assert t.orthocenter == S( """Point(-780660869050599840216997""" """79471538701955848721853/80368430960602242240789074233100000000000000,""" """20151573611150265741278060334545897615974257/16073686192120448448157""" """8148466200000000000)""" ) # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon(Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5) / 4), Point(1, Rational(5) / 4), Point(1, Rational(9) / 4), Point(0, Rational(9) / 4) ) p3 = Polygon(Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon(Point(1, 1), Point(Rational(6) / 5, 1), Point(1, Rational(6) / 5)) pt1 = Point(half, half) pt2 = Point(1, 1) """Polygon to Point""" assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3) / 4 assert p3.distance(pt2) == sqrt(2) / 2
def test_is_tangent(): e1 = Ellipse(Point(0, 0), 3, 5) c1 = Circle(Point(2, -2), 7) assert e1.is_tangent(Point(0, 0)) is False assert e1.is_tangent(Point(3, 0)) is False assert e1.is_tangent(e1) is True assert e1.is_tangent(Ellipse((0, 0), 1, 2)) is False assert e1.is_tangent(Ellipse((0, 0), 3, 2)) is True assert c1.is_tangent(Ellipse((2, -2), 7, 1)) is True assert c1.is_tangent(Circle((11, -2), 2)) is True assert c1.is_tangent(Circle((7, -2), 2)) is True assert c1.is_tangent(Ray((-5, -2), (-15, -20))) is False assert c1.is_tangent(Ray((-3, -2), (-15, -20))) is False assert c1.is_tangent(Ray((-3, -22), (15, 20))) is False assert c1.is_tangent(Ray((9, 20), (9, -20))) is True assert e1.is_tangent(Segment((2, 2), (-7, 7))) is False assert e1.is_tangent(Segment((0, 0), (1, 2))) is False assert c1.is_tangent(Segment((0, 0), (-5, -2))) is False assert e1.is_tangent(Segment((3, 0), (12, 12))) is False assert e1.is_tangent(Segment((12, 12), (3, 0))) is False assert e1.is_tangent(Segment((-3, 0), (3, 0))) is False assert e1.is_tangent(Segment((-3, 5), (3, 5))) is True assert e1.is_tangent(Line((0, 0), (1, 1))) is False assert e1.is_tangent(Line((-3, 0), (-2.99, -0.001))) is False assert e1.is_tangent(Line((-3, 0), (-3, 1))) is True assert e1.is_tangent(Polygon((0, 0), (5, 5), (5, -5))) is False assert e1.is_tangent(Polygon((-100, -50), (-40, -334), (-70, -52))) is False assert e1.is_tangent(Polygon((-3, 0), (3, 0), (0, 1))) is False assert e1.is_tangent(Polygon((-3, 0), (3, 0), (0, 5))) is False assert e1.is_tangent(Polygon((-3, 0), (0, -5), (3, 0), (0, 5))) is False assert e1.is_tangent(Polygon((-3, -5), (-3, 5), (3, 5), (3, -5))) is True assert c1.is_tangent(Polygon((-3, -5), (-3, 5), (3, 5), (3, -5))) is False assert e1.is_tangent(Polygon((0, 0), (3, 0), (7, 7), (0, 5))) is False assert e1.is_tangent(Polygon((3, 12), (3, -12), (6, 5))) is True assert e1.is_tangent(Polygon((3, 12), (3, -12), (0, -5), (0, 5))) is False assert e1.is_tangent(Polygon((3, 0), (5, 7), (6, -5))) is False raises(TypeError, lambda: e1.is_tangent(Point(0, 0, 0))) raises(TypeError, lambda: e1.is_tangent(Rational(5)))
def test_ellipse_geom(): x = Symbol('x', real=True) y = Symbol('y', real=True) t = Symbol('t', real=True) y1 = Symbol('y1', real=True) half = Rational(1, 2) p1 = Point(0, 0) p2 = Point(1, 1) p4 = Point(0, 1) e1 = Ellipse(p1, 1, 1) e2 = Ellipse(p2, half, 1) e3 = Ellipse(p1, y1, y1) c1 = Circle(p1, 1) c2 = Circle(p2, 1) c3 = Circle(Point(sqrt(2), sqrt(2)), 1) l1 = Line(p1, p2) # Test creation with three points cen, rad = Point(3 * half, 2), 5 * half assert Circle(Point(0, 0), Point(3, 0), Point(0, 4)) == Circle(cen, rad) assert Circle(Point(0, 0), Point(1, 1), Point(2, 2)) == Segment2D(Point2D(0, 0), Point2D(2, 2)) raises(ValueError, lambda: Ellipse(None, None, None, 1)) raises(GeometryError, lambda: Circle(Point(0, 0))) # Basic Stuff assert Ellipse(None, 1, 1).center == Point(0, 0) assert e1 == c1 assert e1 != e2 assert e1 != l1 assert p4 in e1 assert p2 not in e2 assert e1.area == pi assert e2.area == pi / 2 assert e3.area == pi * y1 * abs(y1) assert c1.area == e1.area assert c1.circumference == e1.circumference assert e3.circumference == 2 * pi * y1 assert e1.plot_interval() == e2.plot_interval() == [t, -pi, pi] assert e1.plot_interval(x) == e2.plot_interval(x) == [x, -pi, pi] assert c1.minor == 1 assert c1.major == 1 assert c1.hradius == 1 assert c1.vradius == 1 assert Ellipse((1, 1), 0, 0) == Point(1, 1) assert Ellipse((1, 1), 1, 0) == Segment(Point(0, 1), Point(2, 1)) assert Ellipse((1, 1), 0, 1) == Segment(Point(1, 0), Point(1, 2)) # Private Functions assert hash(c1) == hash(Circle(Point(1, 0), Point(0, 1), Point(0, -1))) assert c1 in e1 assert (Line(p1, p2) in e1) is False assert e1.__cmp__(e1) == 0 assert e1.__cmp__(Point(0, 0)) > 0 # Encloses assert e1.encloses(Segment(Point(-0.5, -0.5), Point(0.5, 0.5))) is True assert e1.encloses(Line(p1, p2)) is False assert e1.encloses(Ray(p1, p2)) is False assert e1.encloses(e1) is False assert e1.encloses( Polygon(Point(-0.5, -0.5), Point(-0.5, 0.5), Point(0.5, 0.5))) is True assert e1.encloses(RegularPolygon(p1, 0.5, 3)) is True assert e1.encloses(RegularPolygon(p1, 5, 3)) is False assert e1.encloses(RegularPolygon(p2, 5, 3)) is False assert e2.arbitrary_point() in e2 # Foci f1, f2 = Point(sqrt(12), 0), Point(-sqrt(12), 0) ef = Ellipse(Point(0, 0), 4, 2) assert ef.foci in [(f1, f2), (f2, f1)] # Tangents v = sqrt(2) / 2 p1_1 = Point(v, v) p1_2 = p2 + Point(half, 0) p1_3 = p2 + Point(0, 1) assert e1.tangent_lines(p4) == c1.tangent_lines(p4) assert e2.tangent_lines(p1_2) == [ Line(Point(S(3) / 2, 1), Point(S(3) / 2, S(1) / 2)) ] assert e2.tangent_lines(p1_3) == [Line(Point(1, 2), Point(S(5) / 4, 2))] assert c1.tangent_lines(p1_1) != [Line(p1_1, Point(0, sqrt(2)))] assert c1.tangent_lines(p1) == [] assert e2.is_tangent(Line(p1_2, p2 + Point(half, 1))) assert e2.is_tangent(Line(p1_3, p2 + Point(half, 1))) assert c1.is_tangent(Line(p1_1, Point(0, sqrt(2)))) assert e1.is_tangent(Line(Point(0, 0), Point(1, 1))) is False assert c1.is_tangent(e1) is True assert c1.is_tangent(Ellipse(Point(2, 0), 1, 1)) is True assert c1.is_tangent(Polygon(Point(1, 1), Point(1, -1), Point(2, 0))) is True assert c1.is_tangent(Polygon(Point(1, 1), Point(1, 0), Point(2, 0))) is False assert Circle(Point(5, 5), 3).is_tangent(Circle(Point(0, 5), 1)) is False assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(S(77)/25, S(132)/25)), Line(Point(0, 0), Point(S(33)/5, S(22)/5))] assert Ellipse(Point(5, 5), 2, 1).tangent_lines(Point(3, 4)) == \ [Line(Point(3, 4), Point(4, 4)), Line(Point(3, 4), Point(3, 5))] assert Circle(Point(5, 5), 2).tangent_lines(Point(3, 3)) == \ [Line(Point(3, 3), Point(4, 3)), Line(Point(3, 3), Point(3, 4))] assert Circle(Point(5, 5), 2).tangent_lines(Point(5 - 2*sqrt(2), 5)) == \ [Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 - sqrt(2))), Line(Point(5 - 2*sqrt(2), 5), Point(5 - sqrt(2), 5 + sqrt(2))), ] # for numerical calculations, we shouldn't demand exact equality, # so only test up to the desired precision def lines_close(l1, l2, prec): """ tests whether l1 and 12 are within 10**(-prec) of each other """ return abs(l1.p1 - l2.p1) < 10**(-prec) and abs(l1.p2 - l2.p2) < 10**(-prec) def line_list_close(ll1, ll2, prec): return all(lines_close(l1, l2, prec) for l1, l2 in zip(ll1, ll2)) e = Ellipse(Point(0, 0), 2, 1) assert e.normal_lines(Point(0, 0)) == \ [Line(Point(0, 0), Point(0, 1)), Line(Point(0, 0), Point(1, 0))] assert e.normal_lines(Point(1, 0)) == \ [Line(Point(0, 0), Point(1, 0))] assert e.normal_lines((0, 1)) == \ [Line(Point(0, 0), Point(0, 1))] assert line_list_close(e.normal_lines(Point(1, 1), 2), [ Line(Point(-S(51) / 26, -S(1) / 5), Point(-S(25) / 26, S(17) / 83)), Line(Point(S(28) / 29, -S(7) / 8), Point(S(57) / 29, -S(9) / 2)) ], 2) # test the failure of Poly.intervals and checks a point on the boundary p = Point(sqrt(3), S.Half) assert p in e assert line_list_close(e.normal_lines(p, 2), [ Line(Point(-S(341) / 171, -S(1) / 13), Point(-S(170) / 171, S(5) / 64)), Line(Point(S(26) / 15, -S(1) / 2), Point(S(41) / 15, -S(43) / 26)) ], 2) # be sure to use the slope that isn't undefined on boundary e = Ellipse((0, 0), 2, 2 * sqrt(3) / 3) assert line_list_close(e.normal_lines((1, 1), 2), [ Line(Point(-S(64) / 33, -S(20) / 71), Point(-S(31) / 33, S(2) / 13)), Line(Point(1, -1), Point(2, -4)) ], 2) # general ellipse fails except under certain conditions e = Ellipse((0, 0), x, 1) assert e.normal_lines((x + 1, 0)) == [Line(Point(0, 0), Point(1, 0))] raises(NotImplementedError, lambda: e.normal_lines((x + 1, 1))) # Properties major = 3 minor = 1 e4 = Ellipse(p2, minor, major) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major * (1 - ecc) assert e4.apoapsis == major * (1 + ecc) assert e4.semilatus_rectum == major * (1 - ecc**2) # independent of orientation e4 = Ellipse(p2, major, minor) assert e4.focus_distance == sqrt(major**2 - minor**2) ecc = e4.focus_distance / major assert e4.eccentricity == ecc assert e4.periapsis == major * (1 - ecc) assert e4.apoapsis == major * (1 + ecc) # Intersection l1 = Line(Point(1, -5), Point(1, 5)) l2 = Line(Point(-5, -1), Point(5, -1)) l3 = Line(Point(-1, -1), Point(1, 1)) l4 = Line(Point(-10, 0), Point(0, 10)) pts_c1_l3 = [ Point(sqrt(2) / 2, sqrt(2) / 2), Point(-sqrt(2) / 2, -sqrt(2) / 2) ] assert intersection(e2, l4) == [] assert intersection(c1, Point(1, 0)) == [Point(1, 0)] assert intersection(c1, l1) == [Point(1, 0)] assert intersection(c1, l2) == [Point(0, -1)] assert intersection(c1, l3) in [pts_c1_l3, [pts_c1_l3[1], pts_c1_l3[0]]] assert intersection(c1, c2) == [Point(0, 1), Point(1, 0)] assert intersection(c1, c3) == [Point(sqrt(2) / 2, sqrt(2) / 2)] assert e1.intersection(l1) == [Point(1, 0)] assert e2.intersection(l4) == [] assert e1.intersection(Circle(Point(0, 2), 1)) == [Point(0, 1)] assert e1.intersection(Circle(Point(5, 0), 1)) == [] assert e1.intersection(Ellipse(Point(2, 0), 1, 1)) == [Point(1, 0)] assert e1.intersection(Ellipse(Point(5, 0), 1, 1)) == [] assert e1.intersection(Point(2, 0)) == [] assert e1.intersection(e1) == e1 assert intersection(Ellipse(Point(0, 0), 2, 1), Ellipse(Point(3, 0), 1, 2)) == [Point(2, 0)] assert intersection(Circle(Point(0, 0), 2), Circle(Point(3, 0), 1)) == [Point(2, 0)] assert intersection(Circle(Point(0, 0), 2), Circle(Point(7, 0), 1)) == [] assert intersection(Ellipse(Point(0, 0), 5, 17), Ellipse(Point(4, 0), 1, 0.2)) == [Point(5, 0)] assert intersection(Ellipse(Point(0, 0), 5, 17), Ellipse(Point(4, 0), 0.999, 0.2)) == [] assert Circle((0, 0), S(1) / 2).intersection(Triangle( (-1, 0), (1, 0), (0, 1))) == [Point(-S(1) / 2, 0), Point(S(1) / 2, 0)] raises(TypeError, lambda: intersection(e2, Line((0, 0, 0), (0, 0, 1)))) raises(TypeError, lambda: intersection(e2, Rational(12))) # some special case intersections csmall = Circle(p1, 3) cbig = Circle(p1, 5) cout = Circle(Point(5, 5), 1) # one circle inside of another assert csmall.intersection(cbig) == [] # separate circles assert csmall.intersection(cout) == [] # coincident circles assert csmall.intersection(csmall) == csmall v = sqrt(2) t1 = Triangle(Point(0, v), Point(0, -v), Point(v, 0)) points = intersection(t1, c1) assert len(points) == 4 assert Point(0, 1) in points assert Point(0, -1) in points assert Point(v / 2, v / 2) in points assert Point(v / 2, -v / 2) in points circ = Circle(Point(0, 0), 5) elip = Ellipse(Point(0, 0), 5, 20) assert intersection(circ, elip) in \ [[Point(5, 0), Point(-5, 0)], [Point(-5, 0), Point(5, 0)]] assert elip.tangent_lines(Point(0, 0)) == [] elip = Ellipse(Point(0, 0), 3, 2) assert elip.tangent_lines(Point(3, 0)) == \ [Line(Point(3, 0), Point(3, -12))] e1 = Ellipse(Point(0, 0), 5, 10) e2 = Ellipse(Point(2, 1), 4, 8) a = S(53) / 17 c = 2 * sqrt(3991) / 17 ans = [Point(a - c / 8, a / 2 + c), Point(a + c / 8, a / 2 - c)] assert e1.intersection(e2) == ans e2 = Ellipse(Point(x, y), 4, 8) c = sqrt(3991) ans = [ Point(-c / 68 + a, 2 * c / 17 + a / 2), Point(c / 68 + a, -2 * c / 17 + a / 2) ] assert [p.subs({x: 2, y: 1}) for p in e1.intersection(e2)] == ans # Combinations of above assert e3.is_tangent(e3.tangent_lines(p1 + Point(y1, 0))[0]) e = Ellipse((1, 2), 3, 2) assert e.tangent_lines(Point(10, 0)) == \ [Line(Point(10, 0), Point(1, 0)), Line(Point(10, 0), Point(S(14)/5, S(18)/5))] # encloses_point e = Ellipse((0, 0), 1, 2) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point(e.center + Point(e.hradius + Rational(1, 10), 0)) is False e = Ellipse((0, 0), 2, 1) assert e.encloses_point(e.center) assert e.encloses_point(e.center + Point(0, e.vradius - Rational(1, 10))) assert e.encloses_point(e.center + Point(e.hradius - Rational(1, 10), 0)) assert e.encloses_point(e.center + Point(e.hradius, 0)) is False assert e.encloses_point(e.center + Point(e.hradius + Rational(1, 10), 0)) is False assert c1.encloses_point(Point(1, 0)) is False assert c1.encloses_point(Point(0.3, 0.4)) is True assert e.scale(2, 3) == Ellipse((0, 0), 4, 3) assert e.scale(3, 6) == Ellipse((0, 0), 6, 6) assert e.rotate(pi) == e assert e.rotate(pi, (1, 2)) == Ellipse(Point(2, 4), 2, 1) raises(NotImplementedError, lambda: e.rotate(pi / 3)) # Circle rotation tests (Issue #11743) # Link - https://github.com/sympy/sympy/issues/11743 cir = Circle(Point(1, 0), 1) assert cir.rotate(pi / 2) == Circle(Point(0, 1), 1) assert cir.rotate(pi / 3) == Circle(Point(S(1) / 2, sqrt(3) / 2), 1) assert cir.rotate(pi / 3, Point(1, 0)) == Circle(Point(1, 0), 1) assert cir.rotate(pi / 3, Point(0, 1)) == Circle( Point(S(1) / 2 + sqrt(3) / 2, S(1) / 2 + sqrt(3) / 2), 1)
def test_polygon(): t = Triangle(Point(0, 0), Point(2, 0), Point(3, 3)) assert Polygon(Point(0, 0), Point(1, 0), Point(2, 0), Point(3, 3)) == t assert Polygon(Point(1, 0), Point(2, 0), Point(3, 3), Point(0, 0)) == t assert Polygon(Point(2, 0), Point(3, 3), Point(0, 0), Point(1, 0)) == t p1 = Polygon( Point(0, 0), Point(3,-1), Point(6, 0), Point(4, 5), Point(2, 3), Point(0, 3)) p2 = Polygon( Point(6, 0), Point(3,-1), Point(0, 0), Point(0, 3), Point(2, 3), Point(4, 5)) p3 = Polygon( Point(0, 0), Point(3, 0), Point(5, 2), Point(4, 4)) p4 = Polygon( Point(0, 0), Point(4, 4), Point(5, 2), Point(3, 0)) # # General polygon # assert p1 == p2 assert len(p1) == 6 assert len(p1.sides) == 6 assert p1.perimeter == 5+2*sqrt(10)+sqrt(29)+sqrt(8) assert p1.area == 22 assert not p1.is_convex() assert p3.is_convex() assert p4.is_convex() # ensure convex for both CW and CCW point specification # # Regular polygon # p1 = RegularPolygon(Point(0, 0), 10, 5) p2 = RegularPolygon(Point(0, 0), 5, 5) assert p1 != p2 assert p1.interior_angle == 3*pi/5 assert p1.exterior_angle == 2*pi/5 assert p2.apothem == 5*cos(pi/5) assert p2.circumcircle == Circle(Point(0, 0), 5) assert p2.incircle == Circle(Point(0, 0), p2.apothem) assert p1.is_convex() assert p1.rotation == 0 p1.spin(pi/3) assert p1.rotation == pi/3 assert p1[0] == Point(5, 5*sqrt(3)) # while spin works in place (notice that rotation is 2pi/3 below) # rotate returns a new object p1_old = p1 assert p1.rotate(pi/3) == RegularPolygon(Point(0, 0), 10, 5, 2*pi/3) assert p1 == p1_old # # Angles # angles = p4.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) angles = p3.angles assert feq(angles[Point(0, 0)].evalf(), Float("0.7853981633974483")) assert feq(angles[Point(4, 4)].evalf(), Float("1.2490457723982544")) assert feq(angles[Point(5, 2)].evalf(), Float("1.8925468811915388")) assert feq(angles[Point(3, 0)].evalf(), Float("2.3561944901923449")) # # Triangle # p1 = Point(0, 0) p2 = Point(5, 0) p3 = Point(0, 5) t1 = Triangle(p1, p2, p3) t2 = Triangle(p1, p2, Point(Rational(5,2), sqrt(Rational(75,4)))) t3 = Triangle(p1, Point(x1, 0), Point(0, x1)) s1 = t1.sides # Basic stuff assert Triangle(p1, p1, p1) == p1 assert Triangle(p2, p2*2, p2*3) == Segment(p2, p2*3) assert t1.area == Rational(25,2) assert t1.is_right() assert t2.is_right() == False assert t3.is_right() assert p1 in t1 assert t1.sides[0] in t1 assert Segment((0, 0), (1, 0)) in t1 assert Point(5, 5) not in t2 assert t1.is_convex() assert feq(t1.angles[p1].evalf(), pi.evalf()/2) assert t1.is_equilateral() == False assert t2.is_equilateral() assert t3.is_equilateral() == False assert are_similar(t1, t2) == False assert are_similar(t1, t3) assert are_similar(t2, t3) == False # Bisectors bisectors = t1.bisectors() assert bisectors[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) ic = (250 - 125*sqrt(2)) / 50 assert t1.incenter == Point(ic, ic) # Inradius assert t1.inradius == 5 - 5*sqrt(2)/2 assert t2.inradius == 5*sqrt(3)/6 assert t3.inradius == x1**2/((2 + sqrt(2))*Abs(x1)) # Medians + Centroid m = t1.medians assert t1.centroid == Point(Rational(5,3), Rational(5,3)) assert m[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) assert t3.medians[p1] == Segment(p1, Point(x1/2, x1/2)) assert intersection(m[p1], m[p2], m[p3]) == [t1.centroid] # Perpendicular altitudes = t1.altitudes assert altitudes[p1] == Segment(p1, Point(Rational(5,2), Rational(5,2))) assert altitudes[p2] == s1[0] assert altitudes[p3] == s1[2] # Ensure assert len(intersection(*bisectors.values())) == 1 assert len(intersection(*altitudes.values())) == 1 assert len(intersection(*m.values())) == 1 # Distance p1 = Polygon( Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)) p2 = Polygon( Point(0, Rational(5)/4), Point(1, Rational(5)/4), Point(1, Rational(9)/4), Point(0, Rational(9)/4)) p3 = Polygon( Point(1, 2), Point(2, 2), Point(2, 1)) p4 = Polygon( Point(1, 1), Point(Rational(6)/5, 1), Point(1, Rational(6)/5)) pt1 = Point(half, half) pt2 = Point(1, 1) '''Polygon to Point''' assert p1.distance(pt1) == half assert p1.distance(pt2) == 0 assert p2.distance(pt1) == Rational(3)/4 assert p3.distance(pt2) == sqrt(2)/2