def get_dist_from_line_segment(x1, c, x2, p, sig1, sig2): '''Given three colinear points, x1, c, x2 (geometric order), this program checks if point p and x1 are on the same side of a perpendicular to line segment x1x2 drawn at c. If p and x1 are on the same side of perpendicular line, the distance of p from line segment x1x2 is divided by sig1 (for scaling) or by sig2 otherwise. Inputs: x1, c, x2, p: Np.array of size 2. sig1, sig2: scaling standard deviation Output: l1: Equivalent of l1 distance from the line segment x1x2 (scaled by sigma)''' assert isinstance_multiple( [x1, x2, c], np.ndarray), "Either x1,x2 or c isn't a np.ndarray, check" assert x1.size == x2.size == c.size == 2, "x1, x2, c must contain ony 2 elements" assert isinstance_multiple( [sig1, sig2], float), "Either sig1 or sig2 is not of type float, check" assert not (sig1 < 0.001 or sig2 < 0.001), "sig1, sig2 is smaller than 0.001 (eps), check" x1, x2, c, p = [Point2D(i) for i in [x1, x2, c, p]] S = Segment2D(x1, x2) L = S.perpendicular_line(c) Sc = Segment2D(x1, p) l1 = S.distance(p).evalf() if isinstance(L.intersect(Sc), EmptySet): l1 = l1 / sig1 else: l1 = l1 / sig2 return float(l1)
def inv_replace(G, temp): """Return the nodes replaced by temporary node and build a Steiner point. Arguments: G -- a graph temp -- temporary node """ neighbor = next(G.neighbors(temp)) u, v = temp u_v = Segment2D(G.nodes[u]['pos'], G.nodes[v]['pos']) temp_neighbor = Segment2D(G.nodes[temp]['pos'], G.nodes[neighbor]['pos']) if temp_neighbor.intersect(u_v): circle = Circle(G.nodes[temp]['pos'], G.nodes[u]['pos'], G.nodes[v]['pos']) points = circle.intersect(temp_neighbor) steiner_point = next((p for p in points if p != G.node[temp]['pos'])) G.add_node(steiner_point, pos=steiner_point, color=steiner_color) G.add_path([u, steiner_point, v]) G.add_edge(neighbor, steiner_point) else: if G.nodes[neighbor]['pos'].distance( G.nodes[u]['pos']) > G.nodes[neighbor]['pos'].distance( G.nodes[v]['pos']): G.add_path([u, v, neighbor]) else: G.add_path([v, u, neighbor]) G.remove_node(temp)
def getPointOfIntersection(extreme_points): '''This function returns a unique point of intersection (if it exists) between four points in 2D plane. Input: extreme_points: (4,2) numpy array containing (x,y) coordinates of four points Output: intersection_point: A list containing [xint, yint] NOTE: This function errors out (ValueError) unless the intersection is a unique point. Implement error catching if this is undesired.''' assert isinstance( extreme_points, np.ndarray), "Exteme points should be passed as an ndarray" assert extreme_points.shape == ( 4, 2), "Extreme point array shape must be (4,2)" # We try a random pairing based search. We make three attempts # to try unique pairings of fours points and look for the combination that gives # a unique intersection point. pairings = [[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 1, 2]] intersection_found = False i = 0 pairs = [] while intersection_found is not True and i < 3: pairs = pairings[i] x1 = Point2D(extreme_points[pairs[0], :]) x2 = Point2D(extreme_points[pairs[1], :]) x3 = Point2D(extreme_points[pairs[2], :]) x4 = Point2D(extreme_points[pairs[3], :]) # We use segment over line to ensure the intersection point lies within # the bounding box defined by the extreme points intersection_point = intersection(Segment2D(x1, x2), Segment2D(x3, x4)) # Ensure that intersection point is a unique point and not a line or empty if not intersection_point == []: if isinstance(intersection_point[0], Point2D): intersection_found = True xint, yint = intersection_point[0] i = i + 1 if intersection_found is not True: raise ValueError( "No intersection point was found for given extreme points using random pairing. Check" ) intersection_point = np.array( [np.float128(xint.evalf()), np.float128(yint.evalf())]) pairs = np.array(pairs) return intersection_point, pairs
def intersection_with_circle(self, point1, point2): r = self.r_small_circle R = self.big_circle[2] try: # Point A, B and C A = Point2D(self.big_circle[0], self.big_circle[1]) B = Point2D(point1[0], point1[1]) C = Point2D(point2[0], point2[1]) # Segment from B to C - line line = Segment2D(B, C) c = Circle(A, R + r) result_of_intersect = c.intersection(line) # print(result_of_intersect) temp1 = result_of_intersect[0] temp2 = result_of_intersect[1] temp1 = str(temp1)[7:] temp2 = str(temp2)[7:] # print(temp1) # print(temp2) # print(eval(temp1)) # print(eval(temp2)) p1 = eval(temp1) p2 = eval(temp2) # point1 = mlines.Line2D([p1[0], p2[0]], [p1[1], p2[1]], color='b') # self.figure.gca().add_line(point1) return p1, p2 except: return -666
def get_shortest_route(start: Point2D, end: Point2D, icebergs: List[Polygon]) -> List[Point2D]: """Calculate the best safe route from `start` to `end`. A safe route is one where you don't hit any icebergs. """ # Create a graph where nodes are all the given points - source, # destination, and all points on all the icebergs. graph = Graph() graph.add_node(start) graph.add_node(end) for iceberg in icebergs: graph.add_nodes_from(iceberg.vertices) # For every two nodes on the graph (which are points on the map), we check # if the segment / route between them is blocked. If not, we add a graph # edge between them with the distance as weight. for u, v in combinations(graph.nodes(), r=2): segment = Segment2D(u, v) for iceberg in icebergs: # If we try to travel between adjacent points on an iceberg, # there can't be a collision. if segment in iceberg.sides: continue # Since icebergs are convex, any segment between two non-adjacent # points on the iceberg are blocked by the iceberg itself. if u in iceberg.vertices and v in iceberg.vertices: break # The intersection is a list of points and segments. intersection = segment.intersection(iceberg) if not intersection: continue # If the intersection is the source or the destination point, # then it's okay. It's also fine if we walk alongside the iceberg. if len(intersection) == 1 and (intersection[0] in (u, v) or intersection[0] in iceberg.sides): continue # In any other case, there's a bad collision. break else: graph.add_edge(u, v, {'distance': u.distance(v)}) # Now that we have the graph with proper distances, we can use a shortest # path algorithm (e.g., Dijkstra) to find the shortest path. return shortest_path(graph, source=start, target=end, weight='distance')
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: if poly not in result: if poly is S.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 __init__(self, current_position, old_position): curr = Point2D(current_position[0],current_position[1]) old = Point2D(old_position[0],old_position[1]) self.seg = Segment2D(Point2D(curr), Point2D(old))
def polytope_integrate(poly, expr, **kwargs): """Integrates homogeneous functions over polytopes. This function accepts the polytope in `poly` (currently only polygons are implemented) and the function in `expr` (currently only univariate/bivariate polynomials are implemented) and returns the exact integral of `expr` over `poly`. Parameters ========== poly : The input Polygon. expr : The input polynomial. Optional Parameters: clockwise : Binary value to sort input points of the polygon clockwise. max_degree : The maximum degree of any monomial of the input polynomial. 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 is True and isinstance(poly, Polygon): poly = clockwise_sort(poly) expr = S(expr) if isinstance(poly, Polygon): # For Vertex Representation hp_params = hyperplane_parameters(poly) facets = poly.sides else: # For Hyperplane Representation plen = len(poly) intersections = [ intersection(poly[(i - 1) % plen], poly[i]) 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) ] if max_degree is not None: result = {} if not isinstance(expr, list): raise TypeError('Input polynomials must be list of expressions') result_dict = main_integrate(0, facets, hp_params, max_degree) for polys in expr: if polys not in result: if polys is S.Zero: result[S.Zero] = S.Zero continue integral_value = S.Zero monoms = decompose(polys, separate=True) for monom in monoms: if monom.is_number: integral_value += result_dict[1] * monom else: coeff = LC(monom) integral_value += result_dict[monom / coeff] * coeff result[polys] = integral_value return result return main_integrate(expr, facets, hp_params)