This function converts a polyline (created by the fh_path tool) into a path element and coverts every three line segments into a single bezier curve in an attempt to smooth out the free-hand
777905
function(element) {
		var i, points = element.points;
		var N = points.numberOfItems;
		if (N >= 4) {
			// loop through every 3 points and convert to a cubic bezier curve segment
			// 
			// NOTE: this is cheating, it means that every 3 points has the potential to 
			// be a corner instead of treating each point in an equal manner. In general,
			// this technique does not look that good.
			// 
			// I am open to better ideas!
			// 
			// Reading:
			// - http://www.efg2.com/Lab/Graphics/Jean-YvesQueinecBezierCurves.htm
			// - http://www.codeproject.com/KB/graphics/BezierSpline.aspx?msg=2956963
			// - http://www.ian-ko.com/ET_GeoWizards/UserGuide/smooth.htm
			// - http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-der.html
			var curpos = points.getItem(0), prevCtlPt = null;
			var d = [];
			d.push(["M", curpos.x, ",", curpos.y, " C"].join(""));
			for (i = 1; i <= (N-4); i += 3) {
				var ct1 = points.getItem(i);
				var ct2 = points.getItem(i+1);
				var end = points.getItem(i+2);
				
				// if the previous segment had a control point, we want to smooth out
				// the control points on both sides
				if (prevCtlPt) {
					var newpts = svgedit.path.smoothControlPoints( prevCtlPt, ct1, curpos );
					if (newpts && newpts.length == 2) {
						var prevArr = d[d.length-1].split(',');
						prevArr[2] = newpts[0].x;
						prevArr[3] = newpts[0].y;
						d[d.length-1] = prevArr.join(',');
						ct1 = newpts[1];
					}
				}
				
				d.push([ct1.x, ct1.y, ct2.x, ct2.y, end.x, end.y].join(','));
				
				curpos = end;
				prevCtlPt = ct2;
			}
			// handle remaining line segments
			d.push("L");
			while (i < N) {
				var pt = points.getItem(i);
				d.push([pt.x, pt.y].join(","));
				i++;
			}
			d = d.join(" ");

			// create new path element
			element = addSvgElementFromJson({
				"element": "path",
				"curStyles": true,
				"attr": {
					"id": getId(),
					"d": d,
					"fill": "none"
				}
			});
			// No need to call "changed", as this is already done under mouseUp
		}
		return element;
	}
423588
function (pathAnim) {
		var fxProto = Fx.prototype,
			fxStart = fxProto.start,
			morphProto = Fx.Morph.prototype,
			morphCompute = morphProto.compute;

		// override Fx.start to allow animation of SVG element wrappers
		/*jslint unparam: true*//* allow unused parameters in fx functions */
		fxProto.start = function (from, to) {
			var fx = this,
				elem = fx.element;

			// special for animating paths
			if (from.d) {
				//this.fromD = this.element.d.split(' ');
				fx.paths = pathAnim.init(
					elem,
					elem.d,
					fx.toD
				);
			}
			fxStart.apply(fx, arguments);

			return this; // chainable
		};

		// override Fx.step to allow animation of SVG element wrappers
		morphProto.compute = function (from, to, delta) {
			var fx = this,
				paths = fx.paths;

			if (paths) {
				fx.element.attr(
					'd',
					pathAnim.step(paths[0], paths[1], delta, fx.toD)
				);
			} else {
				return morphCompute.apply(fx, arguments);
			}
		};
		/*jslint unparam: false*/
	}
752677
def bezier_point(p, t):
    """"""

    # begin arc support block ########################
    try:
        p.large_arc
        return p.point(t)
    except:
        pass
    # end arc support block ##########################

    deg = len(p) - 1
    if deg == 3:
        return p[0] + t*(
            3*(p[1] - p[0]) + t*(
                3*(p[0] + p[2]) - 6*p[1] + t*(
                    -p[0] + 3*(p[1] - p[2]) + p[3])))
    elif deg == 2:
        return p[0] + t*(
            2*(p[1] - p[0]) + t*(
                p[0] - 2*p[1] + p[2]))
    elif deg == 1:
        return p[0] + t*(p[1] - p[0])
    elif deg == 0:
        return p[0]
    else:
        bern = bernstein(deg, t)
        return sum(bern[k]*p[k] for k in range(deg+1))
1282115
def _contour(f, vertexlabels=None, contourfunc=None, **kwargs):
    ''''''

    if contourfunc is None:
        contourfunc = plt.tricontour
    if vertexlabels is None:
        vertexlabels = ('1','2','3')
    x = np.linspace(0, 1, 100)
    y = np.linspace(0, np.sqrt(3.0)/2.0, 100)
    points2d = np.transpose([np.tile(x, len(y)), np.repeat(y, len(x))])
    points3d = barycentric(points2d)
    valid = (points3d.sum(axis=1) == 1.0) & ((0.0 <= points3d).all(axis=1))
    points2d = points2d[np.where(valid),:][0]
    points3d = points3d[np.where(valid),:][0]
    z = f(points3d)
    contourfunc(points2d[:,0], points2d[:,1], z, **kwargs)
    _draw_axes(vertexlabels)
    return plt.gcf()
275646
function getPath(points) {
    var p, contours, i, realFirstPoint, j, contour, pt, firstPt,
        prevPt, midPt, curvePt, lastPt;
    p = new path.Path();
    if (!points) {
        return p;
    }
    contours = getContours(points);
    for (i = 0; i < contours.length; i += 1) {
        contour = contours[i];
        firstPt = contour[0];
        lastPt = contour[contour.length - 1];
        if (firstPt.onCurve) {
            curvePt = null;
            // The first point will be consumed by the moveTo command,
            // so skip it in the loop.
            realFirstPoint = true;
        } else {
            if (lastPt.onCurve) {
                // If the first point is off-curve and the last point is on-curve,
                // start at the last point.
                firstPt = lastPt;
            } else {
                // If both first and last points are off-curve, start at their middle.
                firstPt = { x: (firstPt.x + lastPt.x) / 2, y: (firstPt.y + lastPt.y) / 2 };
            }
            curvePt = firstPt;
            // The first point is synthesized, so don't skip the real first point.
            realFirstPoint = false;
        }
        p.moveTo(firstPt.x, firstPt.y);

        for (j = realFirstPoint ? 1 : 0; j < contour.length; j += 1) {
            pt = contour[j];
            prevPt = j === 0 ? firstPt : contour[j - 1];
            if (prevPt.onCurve && pt.onCurve) {
                // This is a straight line.
                p.lineTo(pt.x, pt.y);
            } else if (prevPt.onCurve && !pt.onCurve) {
                curvePt = pt;
            } else if (!prevPt.onCurve && !pt.onCurve) {
                midPt = { x: (prevPt.x + pt.x) / 2, y: (prevPt.y + pt.y) / 2 };
                p.quadraticCurveTo(prevPt.x, prevPt.y, midPt.x, midPt.y);
                curvePt = pt;
            } else if (!prevPt.onCurve && pt.onCurve) {
                // Previous point off-curve, this point on-curve.
                p.quadraticCurveTo(curvePt.x, curvePt.y, pt.x, pt.y);
                curvePt = null;
            } else {
                throw new Error('Invalid state.');
            }
        }
        if (firstPt !== lastPt) {
            // Connect the last and first points
            if (curvePt) {
                p.quadraticCurveTo(curvePt.x, curvePt.y, firstPt.x, firstPt.y);
            } else {
                p.lineTo(firstPt.x, firstPt.y);
            }
        }
    }
    p.closePath();
    return p;
}
1041119
def paint_single_path(self, gstate, stroke, fill, evenodd, path):
        
        if len(path) < 2:
            return
        shape = "".join(x[0] for x in path)

        pts = []
        for p in path:
            for i in range(1, len(p), 2):
                pts.append(apply_matrix_pt(self.ctm, (p[i], p[i + 1])))

        # Line mode
        if self.line_only_shape.match(shape):
            # check for sloped lines first
            has_slope = False
            for i in range(len(pts) - 1):
                if pts[i][0] != pts[i + 1][0] and pts[i][1] != pts[i + 1][1]:
                    has_slope = True
                    break
            if not has_slope:
                for i in range(len(pts) - 1):
                    self.cur_item.add(LTLine(gstate.linewidth, pts[i], pts[i + 1]))

                # Adding the closing line for a polygon, especially rectangles
                if shape.endswith("h"):
                    self.cur_item.add(LTLine(gstate.linewidth, pts[0], pts[-1]))
                return

        # Add the curve as an arbitrary polyline (belzier curve info is lost here)
        self.cur_item.add(LTCurve(gstate.linewidth, pts))
560250
def pts_on_bezier_curve(P=[(0.0, 0.0)], n_seg=0):
    '''
    '''
    assert isinstance(P, list)
    assert len(P) > 0
    for p in P:
        assert isinstance(p, tuple)
        for i in p:
            assert len(p) > 1
            assert isinstance(i, float)
    assert isinstance(n_seg, int)
    assert n_seg >= 0
    
    return [pt_on_bezier_curve(P, float(i)/n_seg) for i in range(n_seg)] + [P[-1]]
1001177
def segment_intersection2(start0, end0, start1, end1):
    """"""
    if NO_IMAGES:
        return

    line0 = bezier.Curve.from_nodes(stack1d(start0, end0))
    line1 = bezier.Curve.from_nodes(stack1d(start1, end1))
    ax = line0.plot(2)
    line1.plot(2, ax=ax)
    ax.axis("scaled")
    save_image(ax.figure, "segment_intersection2.png")
1036444
function hline(x,y,destX) {
  return {
    type:'path',
    x:x,y:y,
    path:["M",x,y,"H",destX],
    'stroke-linecap':'butt',
    'stroke-linejoin':'round',
    'stroke':'#333',
    'stroke-width':2,
    _translate:function (x,y) {
      var p=this.path;
      p[1]+=x;p[2]+=y;p[4]+=x;
    },
  };
}
462104
public static PathPoint curveTo(float c0X, float c0Y, float c1X, float c1Y, float x, float y) {
        return new PathPoint(c0X,  c0Y, c1X, c1Y, x, y);
    }
348547
def draw_path(data, path, draw_options=None, simplify=None):
    
    # For some reasons, matplotlib sometimes adds void paths which consist of
    # only one point and have 0 fill opacity. To not let those clutter the
    # output TeX file, bail out here.
    if (
        len(path.vertices) == 2
        and all(path.vertices[0] == path.vertices[1])
        and "fill opacity=0" in draw_options
    ):
        return data, "", None, False

    nodes = []
    ff = data["float format"]
    prev = None
    for vert, code in path.iter_segments(simplify=simplify):
        # nschloe, Oct 2, 2015:
        #   The transform call yields warnings and it is unclear why. Perhaps
        #   the input data is not suitable? Anyhow, this should not happen.
        #   Comment out for now.
        # vert = numpy.asarray(
        #         _transform_to_data_coordinates(obj, [vert[0]], [vert[1]])
        #         )
        # For path codes see: http://matplotlib.org/api/path_api.html
        #
        # if code == mpl.path.Path.STOP: pass
        is_area = False
        if code == mpl.path.Path.MOVETO:
            nodes.append(("(axis cs:" + ff + "," + ff + ")").format(*vert))
        elif code == mpl.path.Path.LINETO:
            nodes.append(("--(axis cs:" + ff + "," + ff + ")").format(*vert))
        elif code == mpl.path.Path.CURVE3:
            # Quadratic Bezier curves aren't natively supported in TikZ, but
            # can be emulated as cubic Beziers.
            # From
            # http://www.latex-community.org/forum/viewtopic.php?t=4424&f=45:
            # If you really need a quadratic Bézier curve on the points P0, P1
            # and P2, then a process called 'degree elevation' yields the cubic
            # control points (Q0, Q1, Q2 and Q3) as follows:
            #   CODE: SELECT ALL
            #   Q0 = P0
            #   Q1 = 1/3 P0 + 2/3 P1
            #   Q2 = 2/3 P1 + 1/3 P2
            #   Q3 = P2
            #
            # P0 is the point of the previous step which is needed to compute
            # Q1.
            #
            # Cannot draw quadratic Bezier curves as the beginning of of a path
            assert prev is not None
            Q1 = 1.0 / 3.0 * prev + 2.0 / 3.0 * vert[0:2]
            Q2 = 2.0 / 3.0 * vert[0:2] + 1.0 / 3.0 * vert[2:4]
            Q3 = vert[2:4]
            nodes.append(
                (
                    ".. controls (axis cs:"
                    + ff
                    + ","
                    + ff
                    + ") "
                    + "and (axis cs:"
                    + ff
                    + ","
                    + ff
                    + ") "
                    + ".. (axis cs:"
                    + ff
                    + ","
                    + ff
                    + ")"
                ).format(Q1[0], Q1[1], Q2[0], Q2[1], Q3[0], Q3[1])
            )
        elif code == mpl.path.Path.CURVE4:
            # Cubic Bezier curves.
            nodes.append(
                (
                    ".. controls (axis cs:"
                    + ff
                    + ","
                    + ff
                    + ") "
                    + "and (axis cs:"
                    + ff
                    + ","
                    + ff
                    + ") "
                    + ".. (axis cs:"
                    + ff
                    + ","
                    + ff
                    + ")"
                ).format(*vert)
            )
        else:
            assert code == mpl.path.Path.CLOSEPOLY
            nodes.append("--cycle")
            is_area = True

        # Store the previous point for quadratic Beziers.
        prev = vert[0:2]

    do = "[{}]".format(", ".join(draw_options)) if draw_options else ""
    path_command = "\\path {}\n{};\n".format(do, "\n".join(nodes))

    return data, path_command, draw_options, is_area
1199825
function (curve, options, redraw) {
            if (typeof options === "undefined") { options = {}; }
            if (typeof redraw === "undefined") { redraw = false; }
            var screen = this.screen, ctx = this.ctx, prop, opts, path, paths = [], x, y, i, fx, fxold, step = 2 / (screen.scale.x - screen.scale.y), from, to;

            ctx.save();
            ctx.lineWidth = (options.lineWidth || 4) / (screen.scale.x - screen.scale.y);

            // Set the drawing options
            if (options) {
                opts = MathLib.Canvas.convertOptions(options);
                for (prop in opts) {
                    if (opts.hasOwnProperty(prop)) {
                        ctx[prop] = opts[prop];
                    }
                }

                if ('setLineDash' in ctx) {
                    ctx.setLineDash(('dash' in options ? options.dash : []));
                }
                if ('lineDashOffset' in ctx) {
                    ctx.lineDashOffset = ('dashOffset' in options ? options.dashOffset : 0);
                }
            }

            // If curve is a function f, the path will be (x, f(x))
            if (typeof curve === 'function') {
                path = [];
                from = ('from' in options ? (options).from : (-screen.translation.x) / screen.scale.x) - step;
                to = ('to' in options ? (options).to : (screen.width - screen.translation.x) / screen.scale.x) + step;

                for (i = from; i <= to; i += step) {
                    fx = curve(i);

                    // Inline NaN test and disontinuity test
                    // Check if we are drawing a (nearly) vertical line, which should not be there.
                    // i.e the vertical lines at π/2 for the tangent function
                    // TODO: Find a better check if there is a discontinuity.
                    if (fx !== fx || (MathLib.abs((fxold - fx) / step) >= 1e2 && (fx - curve(i - step / 2)) * (fxold - curve(i - step / 2)) >= 0)) {
                        // Don't add empty subpaths
                        if (path.length) {
                            paths.push(path);
                            path = [];
                        }
                    } else {
                        path.push([i, fx]);
                    }

                    fxold = fx;
                }
                if (path.length) {
                    paths.push(path);
                }
            } else if (typeof curve[0] === 'function') {
                path = [];
                x = curve[0];
                y = curve[1];
                from = ('from' in options ? (options).from : 0) - step;
                to = ('to' in options ? (options).to : 2 * Math.PI) + step;
                for (i = from; i <= to; i += step) {
                    path.push([x(i), y(i)]);
                }
                paths.push(path);
            } else {
                path = curve;
            }

            // Draw the path
            // Till now I haven't found a way to stroke and fill the path in one go.
            // The problem is basically, that moveTo creates a new subpath
            // and every subpath is filled on its own.
            if (options.fillColor || options.fillColor !== 'transparent') {
                ctx.beginPath();
                ctx.lineTo(from, 0);
                paths.forEach(function (path) {
                    // The following line (and the line four lines afterwards) fixes the fill at holes in the path.
                    ctx.lineTo(path[0][0], 0);
                    path.forEach(function (x) {
                        ctx.lineTo(x[0], x[1]);
                    });
                    ctx.lineTo(path[path.length - 1][0], 0);
                });
                ctx.fill();
                // ctx.closePath();
            }

            if (options.lineColor || options.lineColor !== 'transparent') {
                ctx.beginPath();
                paths.forEach(function (path) {
                    ctx.moveTo(path[0][0], path[0][1]);
                    path.forEach(function (x) {
                        ctx.lineTo(x[0], x[1]);
                    });
                });
                ctx.stroke();
                // ctx.closePath();
            }

            ctx.restore();

            if (!redraw) {
                if (options.conic) {
                    this.stack.push({
                        type: 'conic',
                        object: options.conic,
                        options: options
                    });
                } else {
                    this.stack.push({
                        type: 'path',
                        object: curve,
                        options: options
                    });
                }
            }

            return this;
        }
1222093
function calculateBezier(t, p0, p1, p2, p3) {
  var mt = 1 - t;
  return mt * mt * mt * p0 + 3 * mt * mt * t * p1 + 3 * mt * t * t * p2 + t * t * t * p3;
}
869185
function normalizePath(path)
{
    if (path.indexOf("..") === -1 && path.indexOf('.') === -1)
        return path;

    var normalizedSegments = [];
    var segments = path.split("/");
    for (var i = 0; i < segments.length; i++) {
        var segment = segments[i];
        if (segment === ".")
            continue;
        else if (segment === "..")
            normalizedSegments.pop();
        else if (segment)
            normalizedSegments.push(segment);
    }
    var normalizedPath = normalizedSegments.join("/");
    if (normalizedPath[normalizedPath.length - 1] === "/")
        return normalizedPath;
    if (path[0] === "/" && normalizedPath)
        normalizedPath = "/" + normalizedPath;
    if ((path[path.length - 1] === "/") || (segments[segments.length - 1] === ".") || (segments[segments.length - 1] === ".."))
        normalizedPath = normalizedPath + "/";

    return normalizedPath;
}
472966
function Line( graph ) {

	// INSTANCE ATTRIBUTES //

	this._parent = graph;
	this._root = undefined;
	this._children = {};
	this._config = {
		"type": "line",
		"interpolation": {
			"mode": "linear",
			"tension": 0.7
		},
		"labels": []
	};

	// DATA //

	this._data = graph._data;

	// TRANSFORMS //

	this._transforms = {
		'x': function X( d ) {
			return graph._xScale( d[ 0 ] );
		},
		'y': function Y( d ) {
			return graph._yScale( d[ 1 ] );
		}
	};

	// GENERATOR //

	this._path = this.path()
		.x( this._transforms.x )
		.y( this._transforms.y )
		.interpolate( this._config.interpolation.mode )
		.tension( this._config.interpolation.tension );

	// REGISTER //
	if ( graph._config.hasOwnProperty( 'marks' ) ) {
		graph._config.marks.push( this._config );
	} else {
		graph._config.marks = [ this._config ];
	}
	if ( graph._children.hasOwnProperty( 'marks' ) ) {
		graph._children.marks.push( this );
	} else {
		graph._children.marks = [ this ];
	}

	return this;
}
65414
function pathRotate(contour, angle, centerX, centerY) {
            angle = angle === undefined ? 0 : angle;
            var x = centerX || 0;
            var y = centerY || 0;
            var cos = Math.cos(angle);
            var sin = Math.sin(angle);
            var px;
            var py;
            var p;

            // x1=cos(angle)*x-sin(angle)*y;
            // y1=cos(angle)*y+sin(angle)*x;
            for (var i = 0, l = contour.length; i < l; i++) {
                p = contour[i];
                px = cos * (p.x - x) - sin * (p.y - y);
                py = cos * (p.y - y) + sin * (p.x - x);
                p.x = px + x;
                p.y = py + y;
            }

            return contour;
        }
30800
function path(d) {
      return line(dimensions.map(function(p) { return [position(p), y[p](d[p])]; }));
    }