示例#1
0
def as_box(quadrant):
    """"Convert a quadrant of the form: ((x_min,y_min),width) to a box: ((x_min,y_min),(x_max,y_max))."""
    width = quadrant[1]
    minp = quadrant[0]
    maxp = tuple(xy + width for xy in minp)
    assert (x(minp) <= x(maxp) and y(minp) <= y(maxp))
    return (minp, maxp)
示例#2
0
def as_box( quadrant ):
    """"Convert a quadrant of the form: ((x_min,y_min),width) to a box: ((x_min,y_min),(x_max,y_max))."""
    width = quadrant[1]
    minp = quadrant[0]
    maxp = tuple(xy+width for xy in minp)
    assert( x(minp) <= x(maxp) and y(minp) <= y(maxp) )
    return (minp,maxp)
示例#3
0
def bounds(vertices):
    """Return the iso-axis rectangle enclosing the given points"""
    # find vertices set bounds
    xmin = x(vertices[0])
    ymin = y(vertices[0])
    xmax = xmin
    ymax = ymin

    # we do not use min(vertices,key=x) because it would iterate 4 times over the list, instead of just one
    for v in vertices:
        xmin = min(x(v), xmin)
        xmax = max(x(v), xmax)
        ymin = min(y(v), ymin)
        ymax = max(y(v), ymax)
    return (xmin, ymin), (xmax, ymax)
示例#4
0
def bounds( vertices ):
    """Return the iso-axis rectangle enclosing the given points"""
    # find vertices set bounds
    xmin = x(vertices[0])
    ymin = y(vertices[0])
    xmax = xmin
    ymax = ymin

    # we do not use min(vertices,key=x) because it would iterate 4 times over the list, instead of just one
    for v in vertices:
        xmin = min(x(v),xmin)
        xmax = max(x(v),xmax)
        ymin = min(y(v),ymin)
        ymax = max(y(v),ymax)
    return (xmin,ymin),(xmax,ymax)
示例#5
0
def circumcircle( triangle, epsilon = sys.float_info.epsilon ):
    """Compute the circumscribed circle of a triangle and 
    Return a 2-tuple: ( (center_x, center_y), radius )"""

    assert( len(triangle) == 3 )
    p0,p1,p2 = triangle
    assert( len(p0) == 2 )
    assert( len(p1) == 2 )
    assert( len(p2) == 2 )

    dy01 = abs( y(p0) - y(p1) )
    dy12 = abs( y(p1) - y(p2) )

    if dy01 < epsilon and dy12 < epsilon:
        # coincident points
        raise CoincidentPointsError

    elif dy01 < epsilon:
        m12 = mtan( p2,p1 )
        mx12,my12 = middle( p1, p2 )
        cx = mid( x, p1, p0 )
        cy = m12 * (cx - mx12) + my12

    elif dy12 < epsilon:
        m01 = mtan( p1, p0 )
        mx01,my01 = middle( p0, p1 )
        cx = mid( x, p2, p1 )
        cy = m01 * ( cx - mx01 ) + my01

    else:
        m01 =  mtan( p1, p0 )
        m12 =  mtan( p2, p1 )
        mx01,my01 = middle( p0, p1 )
        mx12,my12 = middle( p1, p2 )
        cx = ( m01 * mx01 - m12 * mx12 + my12 - my01 ) / ( m01 - m12 )
        if dy01 > dy12:
            cy = m01 * ( cx - mx01 ) + my01
        else:
            cy = m12 * ( cx - mx12 ) + my12

    dx1 = x(p1) - cx
    dy1 = y(p1) - cy
    r = math.sqrt(dx1**2 + dy1**2)

    return (cx,cy),r
示例#6
0
def circumcircle(triangle, epsilon=sys.float_info.epsilon):
    """Compute the circumscribed circle of a triangle and 
    Return a 2-tuple: ( (center_x, center_y), radius )"""

    assert (len(triangle) == 3)
    p0, p1, p2 = triangle
    assert (len(p0) == 2)
    assert (len(p1) == 2)
    assert (len(p2) == 2)

    dy01 = abs(y(p0) - y(p1))
    dy12 = abs(y(p1) - y(p2))

    if dy01 < epsilon and dy12 < epsilon:
        # coincident points
        raise CoincidentPointsError

    elif dy01 < epsilon:
        m12 = mtan(p2, p1)
        mx12, my12 = middle(p1, p2)
        cx = mid(x, p1, p0)
        cy = m12 * (cx - mx12) + my12

    elif dy12 < epsilon:
        m01 = mtan(p1, p0)
        mx01, my01 = middle(p0, p1)
        cx = mid(x, p2, p1)
        cy = m01 * (cx - mx01) + my01

    else:
        m01 = mtan(p1, p0)
        m12 = mtan(p2, p1)
        mx01, my01 = middle(p0, p1)
        mx12, my12 = middle(p1, p2)
        cx = (m01 * mx01 - m12 * mx12 + my12 - my01) / (m01 - m12)
        if dy01 > dy12:
            cy = m01 * (cx - mx01) + my01
        else:
            cy = m12 * (cx - mx12) + my12

    dx1 = x(p1) - cx
    dy1 = y(p1) - cy
    r = math.sqrt(dx1**2 + dy1**2)

    return (cx, cy), r
示例#7
0
    def init( self, quadrant = None, box = None, points = None ):
        """Initialize the root quadrant with the given quadrant, the given box or the given set of points."""

        if len([k for k in (box,points,quadrant) if k]) > 1:
            raise BaseException("ERROR: you should specify a box, a quadrant or points")

        # Initialize the root quadrant as the given box
        if box:
            minp,maxp = box
            width = max( x(maxp)-x(minp), y(maxp)-y(minp) )

        # Initialize the root quadrant as the box around the points
        elif points:
            minp,maxp = geometry.box( points )
            width = max( x(maxp)-x(minp), y(maxp)-y(minp) )

        # Initialize the root quadrant as the given origin point and width
        elif quadrant:
            minp = quadrant[0]
            width = quadrant[1]

        assert( x(minp) <= x(minp)+width and y(minp) <= y(minp)+width )

        # There is always the root quadrant in the list of available ones.
        root = (minp,width)
        quadrants = [ root ]

        return root,quadrants
示例#8
0
    def init(self, quadrant=None, box=None, points=None):
        """Initialize the root quadrant with the given quadrant, the given box or the given set of points."""

        if len([k for k in (box, points, quadrant) if k]) > 1:
            raise BaseException(
                "ERROR: you should specify a box, a quadrant or points")

        # Initialize the root quadrant as the given box
        if box:
            minp, maxp = box
            width = max(x(maxp) - x(minp), y(maxp) - y(minp))

        # Initialize the root quadrant as the box around the points
        elif points:
            minp, maxp = geometry.box(points)
            width = max(x(maxp) - x(minp), y(maxp) - y(minp))

        # Initialize the root quadrant as the given origin point and width
        elif quadrant:
            minp = quadrant[0]
            width = quadrant[1]

        assert (x(minp) <= x(minp) + width and y(minp) <= y(minp) + width)

        # There is always the root quadrant in the list of available ones.
        root = (minp, width)
        quadrants = [root]

        return root, quadrants
示例#9
0
def in_circle( p, center, radius, epsilon  = sys.float_info.epsilon ):
    """Return True if the given point p is in the given circle"""

    assert( len(p) == 2 )
    cx,cy = center

    dxp = x(p) - cx
    dyp = y(p) - cy
    dr = math.sqrt(dxp**2 + dyp**2)

    if (dr - radius) <= epsilon:
        return True
    else:
        return False
示例#10
0
def in_circle(p, center, radius, epsilon=sys.float_info.epsilon):
    """Return True if the given point p is in the given circle"""

    assert (len(p) == 2)
    cx, cy = center

    dxp = x(p) - cx
    dyp = y(p) - cy
    dr = math.sqrt(dxp**2 + dyp**2)

    if (dr - radius) <= epsilon:
        return True
    else:
        return False
示例#11
0
def write( graph, stream ):
    for k in graph:
        stream.write( "%f,%f:" % (x(k),y(k)) )
        for p in graph[k]:
            stream.write( "%f,%f " % (x(p),y(p)) )
        stream.write("\n")
示例#12
0
def turn(p, q, r):
    """Returns -1, 0, 1 if the sequence of points (p,q,r) forms a right, straight, or left turn."""
    qr = (x(q) - x(p)) * (y(r) - y(p))
    rq = (x(r) - x(p)) * (y(q) - y(p))
    # cmp(x,y) returns -1 if x<y, 0 if x==y, +1 if x>y
    return cmp(qr - rq, 0)
示例#13
0
def write_points(points, stream):
    for p in points:
        stream.write("%f,%f\n" % (x(p), y(p)))
示例#14
0
def mtan(pa, pb):
    return -1 * (x(pa) - x(pb)) / (y(pa) - y(pb))
示例#15
0
def write_segments( segments, stream ):
    for seg in segments:
        for p in seg:
            stream.write( "%f,%f " % ( x(p),y(p) ) )
        stream.write( "\n" )
示例#16
0
def write_points( points, stream ):
    for p in points:
        stream.write( "%f,%f\n" % ( x(p),y(p) ) )
示例#17
0
def mtan( pa, pb ):
    return -1 * ( x(pa) - x(pb) ) / ( y(pa) - y(pb) )
示例#18
0
def write(triangles, stream):
    for tri in triangles:
        assert (len(tri) == 3)
        p, q, r = tri
        stream.write("%f,%f %f,%f %f,%f\n" %
                     (x(p), y(p), x(q), y(q), x(r), y(r)))
示例#19
0
def write( triangles, stream ):
    for tri in triangles:
        assert(len(tri)==3)
        p,q,r = tri
        stream.write("%f,%f %f,%f %f,%f\n" % ( x(p),y(p), x(q),y(q), x(r),y(r) ) )
示例#20
0
def in_triangle(p0, triangle, exclude_edges=False):
    """Return True if the given point lies inside the given triangle"""

    p1, p2, p3 = triangle

    # Compute the barycentric coordinates
    alpha = ( (y(p2) - y(p3)) * (x(p0) - x(p3)) + (x(p3) - x(p2)) * (y(p0) - y(p3)) )   \
          / ( (y(p2) - y(p3)) * (x(p1) - x(p3)) + (x(p3) - x(p2)) * (y(p1) - y(p3)) )
    beta  = ( (y(p3) - y(p1)) * (x(p0) - x(p3)) + (x(p1) - x(p3)) * (y(p0) - y(p3)) )   \
          / ( (y(p2) - y(p3)) * (x(p1) - x(p3)) + (x(p3) - x(p2)) * (y(p1) - y(p3)) )
    gamma = 1.0 - alpha - beta

    if exclude_edges:
        # If all of alpha, beta, and gamma are strictly in ]0,1[,
        # then the point p0 strictly lies within the triangle.
        return all(0 < x < 1 for x in (alpha, beta, gamma))
    else:
        # If the inequality is not strict, then the point may lies on an edge.
        return all(0 <= x <= 1 for x in (alpha, beta, gamma))
示例#21
0
def in_triangle( p0, triangle, exclude_edges = False ):
    """Return True if the given point lies inside the given triangle"""

    p1,p2,p3 = triangle

    # Compute the barycentric coordinates
    alpha = ( (y(p2) - y(p3)) * (x(p0) - x(p3)) + (x(p3) - x(p2)) * (y(p0) - y(p3)) )   \
          / ( (y(p2) - y(p3)) * (x(p1) - x(p3)) + (x(p3) - x(p2)) * (y(p1) - y(p3)) )
    beta  = ( (y(p3) - y(p1)) * (x(p0) - x(p3)) + (x(p1) - x(p3)) * (y(p0) - y(p3)) )   \
          / ( (y(p2) - y(p3)) * (x(p1) - x(p3)) + (x(p3) - x(p2)) * (y(p1) - y(p3)) )
    gamma = 1.0 - alpha - beta

    if exclude_edges:
        # If all of alpha, beta, and gamma are strictly in ]0,1[,
        # then the point p0 strictly lies within the triangle.
        return all( 0 < x < 1 for x in (alpha, beta, gamma) )
    else:
        # If the inequality is not strict, then the point may lies on an edge.
        return all( 0 <= x <= 1 for x in (alpha, beta, gamma) )
示例#22
0
def turn(p, q, r):
    """Returns -1, 0, 1 if the sequence of points (p,q,r) forms a right, straight, or left turn."""
    qr = ( x(q) - x(p) ) * ( y(r) - y(p) )
    rq = ( x(r) - x(p) ) * ( y(q) - y(p) )
    # cmp(x,y) returns -1 if x<y, 0 if x==y, +1 if x>y
    return cmp( qr - rq, 0)
示例#23
0
def write_segments(segments, stream):
    for seg in segments:
        for p in seg:
            stream.write("%f,%f " % (x(p), y(p)))
        stream.write("\n")
示例#24
0
def write(graph, stream):
    for k in graph:
        stream.write("%f,%f:" % (x(k), y(k)))
        for p in graph[k]:
            stream.write("%f,%f " % (x(p), y(p)))
        stream.write("\n")