Пример #1
0
def point(path, t, segments=None):
    """ Returns coordinates for point at t on the path.
        Gets the length of the path, based on the length of each curve and line in the path.
        Determines in what segment t falls. Gets the point on that segment.
        When you supply the list of segment lengths yourself, as returned from length(path, segmented=True), 
        point() works about thirty times faster in a for-loop since it doesn't need to recalculate 
        the length during each iteration.
    """
    if len(path) == 0:
        raise PathError, "The given path is empty"
    i, t, closeto = _locate(path, t, segments=segments)
    x0, y0 = path[i].x, path[i].y
    p1 = path[i + 1]
    if p1.cmd == CLOSE:
        x, y = linepoint(t, x0, y0, closeto.x, closeto.y)
        return DynamicPathElement(LINETO, ((x, y), ))
    elif p1.cmd == LINETO:
        x1, y1 = p1.x, p1.y
        x, y = linepoint(t, x0, y0, x1, y1)
        return DynamicPathElement(LINETO, ((x, y), ))
    elif p1.cmd == CURVETO:
        # Note: the handles need to be interpreted differenty than in a BezierPath.
        # In a BezierPath, ctrl1 is how the curve started, and ctrl2 how it arrives in this point.
        # Here, ctrl1 is how the curve arrives, and ctrl2 how it continues to the next point.
        x3, y3, x1, y1, x2, y2 = p1.x, p1.y, p1.ctrl1.x, p1.ctrl1.y, p1.ctrl2.x, p1.ctrl2.y
        x, y, c1x, c1y, c2x, c2y = curvepoint(t, x0, y0, x1, y1, x2, y2, x3,
                                              y3)
        return DynamicPathElement(CURVETO, ((c1x, c1y), (c2x, c2y), (x, y)))
    else:
        raise PathError, "Unknown cmd '%s' for p1 %s" % (p1.cmd, p1)
Пример #2
0
def point(path, t, segments=None):
    """ Returns coordinates for point at t on the path.
        Gets the length of the path, based on the length of each curve and line in the path.
        Determines in what segment t falls. Gets the point on that segment.
        When you supply the list of segment lengths yourself, as returned from length(path, segmented=True), 
        point() works about thirty times faster in a for-loop since it doesn't need to recalculate 
        the length during each iteration.
    """
    if len(path) == 0:
        raise PathError, "The given path is empty"
    i, t, closeto = _locate(path, t, segments=segments)
    x0, y0 = path[i].x, path[i].y
    p1 = path[i+1]
    if p1.cmd == CLOSE:
        x, y = linepoint(t, x0, y0, closeto.x, closeto.y)
        return DynamicPathElement(LINETO, ((x, y),))
    elif p1.cmd == LINETO:
        x1, y1 = p1.x, p1.y
        x, y = linepoint(t, x0, y0, x1, y1)
        return DynamicPathElement(LINETO, ((x, y),))
    elif p1.cmd == CURVETO:
        # Note: the handles need to be interpreted differenty than in a BezierPath.
        # In a BezierPath, ctrl1 is how the curve started, and ctrl2 how it arrives in this point.
        # Here, ctrl1 is how the curve arrives, and ctrl2 how it continues to the next point.
        x3, y3, x1, y1, x2, y2 = p1.x, p1.y, p1.ctrl1.x, p1.ctrl1.y, p1.ctrl2.x, p1.ctrl2.y
        x, y, c1x, c1y, c2x, c2y = curvepoint(t, x0, y0, x1, y1, x2, y2, x3, y3)
        return DynamicPathElement(CURVETO, ((c1x, c1y), (c2x, c2y), (x, y)))
    else:
        raise PathError, "Unknown cmd '%s' for p1 %s" % (p1.cmd, p1)
Пример #3
0
def insert_point(path, t):
    """ Returns a path copy with an extra point at t.
    """
    
    # Find the points before and after t on the path.
    i, t, closeto = _locate(path, t)
    x0 = path[i].x
    y0 = path[i].y
    p1 = path[i+1]
    p1cmd, x3, y3, x1, y1, x2, y2 = p1.cmd, p1.x, p1.y, p1.ctrl1.x, p1.ctrl1.y, p1.ctrl2.x, p1.ctrl2.y
    
    # Construct the new point at t.
    if p1cmd == CLOSE:
        pt_cmd = LINETO
        pt_x, pt_y = linepoint(t, x0, y0, closeto.x, closeto.y)
    elif p1cmd == LINETO:
        pt_cmd = LINETO
        pt_x, pt_y = linepoint(t, x0, y0, x3, y3)
    elif p1cmd == CURVETO:
        pt_cmd = CURVETO
        pt_x, pt_y, pt_c1x, pt_c1y, pt_c2x, pt_c2y, pt_h1x, pt_h1y, pt_h2x, pt_h2y = \
            curvepoint(t, x0, y0, x1, y1, x2, y2, x3, y3, True)
    else:
        raise PathError, "Locate should not return a MOVETO"
    
    new_path = BezierPath(None)
    new_path.moveto(path[0].x, path[0].y)
    for j in range(1, len(path)):
        if j == i+1:
            if pt_cmd == CURVETO:
                new_path.curveto(pt_h1x, pt_h1y, pt_c1x, pt_c1y, pt_x, pt_y)
                new_path.curveto(pt_c2x, pt_c2y, pt_h2x, pt_h2y, path[j].x, path[j].y)
            elif pt_cmd == LINETO:
                new_path.lineto(pt_x, pt_y)
                if path[j].cmd != CLOSE:
                    new_path.lineto(path[j].x, path[j].y)
                else:
                    new_path.closepath()
            else:
                raise PathError, "Didn't expect pt_cmd %s here" % pt_cmd
        else:
            if path[j].cmd == MOVETO:
                new_path.moveto(path[j].x, path[j].y)
            if path[j].cmd == LINETO:
                new_path.lineto(path[j].x, path[j].y)
            if path[j].cmd == CURVETO:
                new_path.curveto(path[j].ctrl1.x, path[j].ctrl1.y,
                             path[j].ctrl2.x, path[j].ctrl2.y,
                             path[j].x, path[j].y)
            if path[j].cmd == CLOSE:
                new_path.closepath()
                
    return new_path
Пример #4
0
def curvelength(x0, y0, x1, y1, x2, y2, x3, y3, n=20):
    """ Returns the length of the spline.
        Integrates the estimated length of the cubic bezier spline defined by x0, y0, ... x3, y3, 
        by adding the lengths of linear lines between points at t.
        The number of points is defined by n 
        (n=10 would add the lengths of lines between 0.0 and 0.1, between 0.1 and 0.2, and so on).
        The default n=20 is fine for most cases, usually resulting in a deviation of less than 0.01.
    """
    length = 0
    xi = x0
    yi = y0
    for i in range(n):
        t = 1.0 * (i + 1) / n
        pt_x, pt_y, pt_c1x, pt_c1y, pt_c2x, pt_c2y = \
            curvepoint(t, x0, y0, x1, y1, x2, y2, x3, y3)
        c = sqrt(pow(abs(xi - pt_x), 2) + pow(abs(yi - pt_y), 2))
        length += c
        xi = pt_x
        yi = pt_y
    return length
Пример #5
0
def curvelength(x0, y0, x1, y1, x2, y2, x3, y3, n=20):
    """ Returns the length of the spline.
        Integrates the estimated length of the cubic bezier spline defined by x0, y0, ... x3, y3, 
        by adding the lengths of lineair lines between points at t.
        The number of points is defined by n 
        (n=10 would add the lengths of lines between 0.0 and 0.1, between 0.1 and 0.2, and so on).
        The default n=20 is fine for most cases, usually resulting in a deviation of less than 0.01.
    """
    length = 0
    xi = x0
    yi = y0
    for i in range(n):
        t = 1.0 * (i+1) / n
        pt_x, pt_y, pt_c1x, pt_c1y, pt_c2x, pt_c2y = \
            curvepoint(t, x0, y0, x1, y1, x2, y2, x3, y3)
        c = sqrt(pow(abs(xi-pt_x),2) + pow(abs(yi-pt_y),2))
        length += c
        xi = pt_x
        yi = pt_y
    return length
Пример #6
0
def insert_point(path, t):
    """ Inserts an extra point at t.
    """

    # Find the points before and after t on the path.
    i, t, closeto = _locate(path, t)
    x0 = path[i].x
    y0 = path[i].y
    p1 = path[i + 1]
    p1cmd, x3, y3, x1, y1, x2, y2 = p1.cmd, p1.x, p1.y, p1.ctrl1.x, p1.ctrl1.y, p1.ctrl2.x, p1.ctrl2.y

    # Construct the new point at t.
    if p1cmd == CLOSE:
        pt_cmd = LINETO
        pt_x, pt_y = linepoint(t, x0, y0, closeto.x, closeto.y)
    elif p1cmd == LINETO:
        pt_cmd = LINETO
        pt_x, pt_y = linepoint(t, x0, y0, x3, y3)
    elif p1cmd == CURVETO:
        pt_cmd = CURVETO
        pt_x, pt_y, pt_c1x, pt_c1y, pt_c2x, pt_c2y, pt_h1x, pt_h1y, pt_h2x, pt_h2y = \
            curvepoint(t, x0, y0, x1, y1, x2, y2, x3, y3, True)
    else:
        raise PathError, "Locate should not return a MOVETO"

    # NodeBox for OpenGL modifies the path in place,
    # NodeBox for Mac OS X returned a path copy (see inactive code below).
    if pt_cmd == CURVETO:
        path[i + 1].ctrl1.x = pt_c2x
        path[i + 1].ctrl1.y = pt_c2y
        path[i + 1].ctrl2.x = pt_h2x
        path[i + 1].ctrl2.y = pt_h2y
        path.insert(
            i + 1,
            PathElement(cmd=CURVETO,
                        pts=[(pt_h1x, pt_h1y), (pt_c1x, pt_c1y),
                             (pt_x, pt_y)]))
    elif pt_cmd == LINETO:
        path.insert(i + 1, PathElement(cmd=LINETO, pts=[(pt_x, pt_y)]))
    else:
        raise PathError, "Didn't expect pt_cmd %s here" % pt_cmd
    return path[i + 1]

    #new_path = BezierPath(None)
    #new_path.moveto(path[0].x, path[0].y)
    #for j in range(1, len(path)):
    #    if j == i+1:
    #        if pt_cmd == CURVETO:
    #            new_path.curveto(pt_h1x, pt_h1y, pt_c1x, pt_c1y, pt_x, pt_y)
    #            new_path.curveto(pt_c2x, pt_c2y, pt_h2x, pt_h2y, path[j].x, path[j].y)
    #        elif pt_cmd == LINETO:
    #            new_path.lineto(pt_x, pt_y)
    #            if path[j].cmd != CLOSE:
    #                new_path.lineto(path[j].x, path[j].y)
    #            else:
    #                new_path.closepath()
    #        else:
    #            raise PathError, "Didn't expect pt_cmd %s here" % pt_cmd
    #    else:
    #        if path[j].cmd == MOVETO:
    #            new_path.moveto(path[j].x, path[j].y)
    #        if path[j].cmd == LINETO:
    #            new_path.lineto(path[j].x, path[j].y)
    #        if path[j].cmd == CURVETO:
    #            new_path.curveto(path[j].ctrl1.x, path[j].ctrl1.y,
    #                         path[j].ctrl2.x, path[j].ctrl2.y,
    #                         path[j].x, path[j].y)
    #        if path[j].cmd == CLOSE:
    #            new_path.closepath()

    return new_path
Пример #7
0
def insert_point(path, t):
    """ Inserts an extra point at t.
    """

    # Find the points before and after t on the path.
    i, t, closeto = _locate(path, t)
    x0 = path[i].x
    y0 = path[i].y
    p1 = path[i+1]
    p1cmd, x3, y3, x1, y1, x2, y2 = p1.cmd, p1.x, p1.y, p1.ctrl1.x, p1.ctrl1.y, p1.ctrl2.x, p1.ctrl2.y

    # Construct the new point at t.
    if p1cmd == CLOSE:
        pt_cmd = LINETO
        pt_x, pt_y = linepoint(t, x0, y0, closeto.x, closeto.y)
    elif p1cmd == LINETO:
        pt_cmd = LINETO
        pt_x, pt_y = linepoint(t, x0, y0, x3, y3)
    elif p1cmd == CURVETO:
        pt_cmd = CURVETO
        pt_x, pt_y, pt_c1x, pt_c1y, pt_c2x, pt_c2y, pt_h1x, pt_h1y, pt_h2x, pt_h2y = \
            curvepoint(t, x0, y0, x1, y1, x2, y2, x3, y3, True)
    else:
        raise Exception("Locate should not return a MOVETO")

    # NodeBox for OpenGL modifies the path in place,
    # NodeBox for Mac OS X returned a path copy (see inactive code below).
    if pt_cmd == CURVETO:
        path[i+1].ctrl1.x = pt_c2x
        path[i+1].ctrl1.y = pt_c2y
        path[i+1].ctrl2.x = pt_h2x
        path[i+1].ctrl2.y = pt_h2y
        path.insert(i+1, PathElement(cmd=CURVETO, pts=[(pt_h1x, pt_h1y), (pt_c1x, pt_c1y), (pt_x, pt_y)]))
    elif pt_cmd == LINETO:
        path.insert(i+1, PathElement(cmd=LINETO, pts=[(pt_x, pt_y)]))
    else:
        raise Exception("Didn't expect pt_cmd %s here" % pt_cmd)
    return path[i+1]
    
    #new_path = BezierPath(None)
    #new_path.moveto(path[0].x, path[0].y)
    #for j in range(1, len(path)):
    #    if j == i+1:
    #        if pt_cmd == CURVETO:
    #            new_path.curveto(pt_h1x, pt_h1y, pt_c1x, pt_c1y, pt_x, pt_y)
    #            new_path.curveto(pt_c2x, pt_c2y, pt_h2x, pt_h2y, path[j].x, path[j].y)
    #        elif pt_cmd == LINETO:
    #            new_path.lineto(pt_x, pt_y)
    #            if path[j].cmd != CLOSE:
    #                new_path.lineto(path[j].x, path[j].y)
    #            else:
    #                new_path.closepath()
    #        else:
    #            raise PathError, "Didn't expect pt_cmd %s here" % pt_cmd
    #    else:
    #        if path[j].cmd == MOVETO:
    #            new_path.moveto(path[j].x, path[j].y)
    #        if path[j].cmd == LINETO:
    #            new_path.lineto(path[j].x, path[j].y)
    #        if path[j].cmd == CURVETO:
    #            new_path.curveto(path[j].ctrl1.x, path[j].ctrl1.y,
    #                         path[j].ctrl2.x, path[j].ctrl2.y,
    #                         path[j].x, path[j].y)
    #        if path[j].cmd == CLOSE:
    #            new_path.closepath()
                
    return new_path