def convexpath(segment: Segment2D, polygons: List[Polygon], q: Queue, visited: Dict[Segment2D, bool]): # get convex hull for source, destination and vertices of polygon for polygon in polygons: points = polygon.vertices points.extend([segment.p1, segment.p2]) hull = convex_hull(*points, polygon=True) for side in hull.sides: if not visited[side]: q.put(side)
def generate_test(n): rand_points = np.random.randint(0, 25, size=(n, 2)) points = [] if n <= 3: return rand_points.tolist() hull = convex_hull(*rand_points) for point in hull.vertices: # points.insert(len(points), [point.x, point.y]) points.append([point.x, point.y]) return points
def reduce(vert_list): a = convex_hull(*vert_list) output2 = [] avert = a.vertices for thing in avert: output2 += [[thing[0], thing[1]]] output4 = [] for i in range(0, len(output2)): if distance(output2[i - 1], output2[i]) < 0.15: continue else: output4 += [output2[i]] return output4
def vertical(poly_vertices): new_polyvertices = poly_vertices for element in poly_vertices: line = Line((element), (element[0], element[1] + 1)) poly = convex_hull(*poly_vertices) inters = poly.intersection(line) for point in inters: if type(point) == Segment2D: continue if point not in new_polyvertices: new_polyvertices += [point] return new_polyvertices
def polygon(F,X,Y,I): """ Computes a set of parameters and polynomials in one-to-one correspondence with the segments fo the Newton polygon of F. If ``I=2`` the correspondence is only with the segments with negative slope. The segment `\Delta` corresponding to the list `(q,m,l,\Phi)` is on the line `qj+mi=l` in the `(i,j)`-plane and .. math: \Phi = \sum_{(i,j) \in \Delta} a_{ij}Z^{(i-i_0)/q} where `i_0` is the smallest value of `i` such that there is a point `(i,j) \in \Delta`. Note that `\Phi \in \mathbb{L}[Z]`. INPUTS: -- ``F``: a polynomial in `\mathbb{L}[X,Y]` -- ``X,Y``: the variable defining ``F`` -- ``I``: a parameter OUTPUTS: -- ``(list)``: a list of tuples `(q,m,l,\Phi)` where `q,m,l` are integers with `(q,m) = 1`, `q>0`, and `\Phi \in \mathbb{L}[Z]`. """ # compute the coefficients and support of F P = sympy.poly(F,X,Y) a = _coefficient(P) support = a.keys() # compute the lower convex hull of F. # # since sympy.convex_hull doesn't include points on edges, we need # to compare back to the support. the convex hull will contain all # points. Those on the boundary are considered "outside" by sympy. hull = sympy.convex_hull(*support) if type(hull) == sympy.Segment: hull_with_bdry = support # colinear support is a newton polygon else: hull_with_bdry = [p for p in support if not hull.encloses(sympy.Point(p))] newton = [] # find the start and end points (0,J) and (I,0). Include points # along the i-axis if I==1. Otherwise, only include points with # negative slope if I==2 JJ = min([j for (i,j) in hull if i == 0]) if I == 2: II = min([i for (i,j) in hull if j == 0]) else: II = max([i for (i,j) in hull if j == 0]) testslope = -float(JJ)/II # determine largest slope with (0,JJ). If this is greater than the # test slope then there exist points above the line connecting # (0,JJ) with (II,0) this fact is used to deal with certain # borderline cases include_borderline_colinear = (type(hull) == sympy.Segment) for (i,j) in hull_with_bdry: # when the point is on the j-axis, the onle one we want is the # point (0,JJ) if i == 0: if j == JJ: slope = -sympy.oo else: slope = sympy.oo else: slope = float(j-JJ)/i if slope > testslope: include_borderline_colinear = True break # loop through all points on the boundary and determine if it's in the # newton polygon using a testslope method for (i,j) in hull_with_bdry: # when the point is on the j-axis, the onle one we want is the # point (0,JJ) if i == 0: if j == JJ: slope = -sympy.oo else: slope = sympy.oo else: slope = float(j-JJ)/i # if the slope is less than the test slope or if we're in the # case where we include points along the j=0 line then add the # point to the newton polygon if (slope < testslope) or (I==1 and j==0): newton.append((i,j)) elif (slope == testslope) and include_borderline_colinear: # borderline case is when there is only one segment from # (0,JJ) to (II,0). When this is the case, include all # points whose slope matches testslope newton.append((i,j)) newton.sort(key=itemgetter(1),reverse=True) # sort second in j-th coord newton.sort(key=itemgetter(0)) # sort first in i-th coord # # now that we have the newton polygon we compute the parameters # (q,m,l,Phi) for each side Delta on the polygon. # params = [] eps = 1e-14 N = len(newton) n = 0 while n < N-1: # determine slope of current line side = [newton[n],newton[n+1]] sideslope = sympy.Rational(side[1][1]-side[0][1],side[1][0]-side[0][0]) # check against all following points for colinearity by # comparing slopes. append all colinear points to side k = 1 for pt in newton[n+2:]: slope = float(pt[1]-side[0][1]) / (pt[0]-side[0][0]) if abs(slope - sideslope) < eps: side.append(pt) k += 1 else: # when we reach the end of the newton polygon we need # to shift the value of k a little bit so that the # last side is correctly captured if k == N-n-1: k -= # 1 break n += k # compute q,m,l such that qj + mi = l and Phi q = sideslope.q m = -sideslope.p l = q*side[0][1] + m*side[0][0] i0 = min(side, key=itemgetter(0))[0] Phi = sum(a[(i,j)]*_Z**sympy.Rational(i-i0,q) for (i,j) in side) Phi = sympy.Poly(Phi,_Z) params.append((q,m,l,Phi)) return params
[395900439989221 / 500000000000000, 758370304316853 / 10000000000000000], [734533839502909 / 1000000000000000, 75690126771387 / 250000000000000], [157501043698323 / 200000000000000, 105068629352711 / 1000000000000000], [183871665699151 / 250000000000000, 300300252818159 / 1000000000000000], [787100260535577 / 1000000000000000, 107675683694887 / 1000000000000000], [-150019573267693 / 200000000000000, -2009881175297 / 10000000000000], [190603603572791 / 250000000000000, 40857665321433 / 200000000000000] ] poly = Polygon((0, 0), 100, n=4) out = [] for e in new_vertices: out += [[float(e[0]), float(e[1])]] poly = convex_hull(*out) angle = 0 for i in range(1, 2): #if i != 0: # poly = convex_hull(*sym) if i % 2 == 2: angle = float(1 / sqrt(2)) + 1 / 12 if i % 2 == 1: angle = 1 / 12 #i = 2*j-1
def symmetrize(poly, angle): #step 1: rotate the polygon rotated_poly = rotate1(poly.vertices, angle) #step 2: add in all the intersection points full_poly = vertical(rotated_poly) #step 3: sort the points by x-coordinate and pair together opposite points. sorted_new_poly_vertices = bubbleSort(full_poly) pairedsorted_newpolyvertices = pairing(sorted_new_poly_vertices) #step 4: average the y-coordinates of the opposite points while keeping x-coords the same. for pair in pairedsorted_newpolyvertices: if len(pair) == 2: item0 = pair[0] item1 = pair[1] item0new = Point(item0[0], 0.5 * (abs(item0[1]) + abs(item1[1]))) item1new = Point(item0[0], -1 * (0.5 * (abs(item0[1]) + abs(item1[1])))) pair[0] = item0new pair[1] = item1new else: pair[0] = Point(pair[0][0], 0) #Step 5: make the pairs of points into a list of points for convenience output = [] for item in pairedsorted_newpolyvertices: output += item #Step 6: Rotating it back to original position. output3 = rotate1(output, 2 * pi - angle) outpoly = convex_hull(*output3) outpolyvert = outpoly.vertices #Step 7: Putting it into Sage format for ease of copy/paste output2 = [] for thing in outpolyvert: output2 += [[thing[0], thing[1]]] output4 = output2 #Step 8: (optional) removing points that are too close (distance < 1) """ if len(output2)>30: output4 = [] for i in range (0,len(output2)): print (i) if distance (output2[i-1],output2[i]) < 0.1: continue else: output4 += [output2[i]] """ return output4
def newton_polygon(H, additional_points=[]): r"""Computes the Newton polygon of `H`. It's assumed that the first generator of `H` here is the "dependent variable". For example, if `H = H(x,y)` and we are aiming to compute a `y`-covering of the complex `x`-sphere then each monomial of `H` is of the form .. math:: a_{ij} x^j y^i. Parameters ---------- H : bivariate polynomial Returns ------- list Returns a list where each element is a list, representing a side of the polygon, which in turn contains tuples representing the points on the side. Note ---- This is written using Sympy's convex hull algorithm for legacy purposes. It can certainly be rewritten to use Sage's Polytope but do so *very carefully*! There are a number of subtle things going on here due to the fact that boundary points are ignored. """ # because of the way sympy.convex_hull computes the convex hull we # need to remove all points of the form (0,j) and (i,0) where j > j0 # and i > i0, the points on the axes closest to the origin R = H.parent() x,y = R.gens() monomials = H.monomials() points = map(lambda monom: (monom.degree(y), monom.degree(x)), monomials) support = map(Point, points) + additional_points i0 = min(P.x for P in support if P.y == 0) j0 = min(P.y for P in support if P.x == 0) support = filter(lambda P: (P.x <= i0) and (P.y <= j0), support) convex_hull = sympy.convex_hull(*support) # special treatment when the hull is just a point or a segment if isinstance(convex_hull, Point): P = (convex_hull.x,convex_hull.y) return [[P]] elif isinstance(convex_hull, Segment): P = convex_hull.p1 convex_hull = generalized_polygon_side(convex_hull) support.remove(P) support.append(convex_hull.p1) sides = [convex_hull] else: # recursive call with generalized point if a generalized newton # polygon is needed. sides = convex_hull.sides first_side = generalized_polygon_side(sides[0]) if first_side != sides[0]: P = first_side.p1 return newton_polygon(H,additional_points=[P]) # convert the sides to lists of points polygon = [] for side in sides: polygon_side = [P for P in support if P in side] polygon_side = sorted(map(lambda P: (int(P.x),int(P.y)), polygon_side)) polygon.append(polygon_side) # stop the moment we hit the i-axis. despite the filtration at # the start of this function we need this condition to prevent # returning to the starting point of the newton polygon. # # (See test_puiseux.TestNewtonPolygon.test_multiple) if side.p2.y == 0: break return polygon
def newton_polygon(H, additional_points=[]): r"""Computes the Newton polygon of `H`. It's assumed that the first generator of `H` here is the "dependent variable". For example, if `H = H(x,y)` and we are aiming to compute a `y`-covering of the complex `x`-sphere then each monomial of `H` is of the form .. math:: a_{ij} x^j y^i. Parameters ---------- H : bivariate polynomial Returns ------- list Returns a list where each element is a list, representing a side of the polygon, which in turn contains tuples representing the points on the side. Note ---- This is written using Sympy's convex hull algorithm for legacy purposes. It can certainly be rewritten to use Sage's Polytope but do so *very carefully*! There are a number of subtle things going on here due to the fact that boundary points are ignored. """ # because of the way sympy.convex_hull computes the convex hull we # need to remove all points of the form (0,j) and (i,0) where j > j0 # and i > i0, the points on the axes closest to the origin R = H.parent() x, y = R.gens() monomials = H.monomials() points = map(lambda monom: (monom.degree(y), monom.degree(x)), monomials) support = map(Point, points) + additional_points i0 = min(P.x for P in support if P.y == 0) j0 = min(P.y for P in support if P.x == 0) support = filter(lambda P: (P.x <= i0) and (P.y <= j0), support) convex_hull = sympy.convex_hull(*support) # special treatment when the hull is just a point or a segment if isinstance(convex_hull, Point): P = (convex_hull.x, convex_hull.y) return [[P]] elif isinstance(convex_hull, Segment): P = convex_hull.p1 convex_hull = generalized_polygon_side(convex_hull) support.remove(P) support.append(convex_hull.p1) sides = [convex_hull] else: # recursive call with generalized point if a generalized newton # polygon is needed. sides = convex_hull.sides first_side = generalized_polygon_side(sides[0]) if first_side != sides[0]: P = first_side.p1 return newton_polygon(H, additional_points=[P]) # convert the sides to lists of points polygon = [] for side in sides: polygon_side = [P for P in support if P in side] polygon_side = sorted(map(lambda P: (int(P.x), int(P.y)), polygon_side)) polygon.append(polygon_side) # stop the moment we hit the i-axis. despite the filtration at # the start of this function we need this condition to prevent # returning to the starting point of the newton polygon. # # (See test_puiseux.TestNewtonPolygon.test_multiple) if side.p2.y == 0: break return polygon