Beispiel #1
0
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)
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
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')
Beispiel #6
0
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)
Beispiel #7
0
 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))
Beispiel #8
0
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)