Returns a tangent line at requested `length` with precision better than requested `opt.precision`; or using `opt.subdivisions` provided.
505509
function(length, opt) {

            if (!this.isDifferentiable()) return null;

            var t = this.tAtLength(length, opt);

            return this.tangentAtT(t);
        }
590935
function(x, y, opt) {

        var position = {};

        var localOpt = opt || {};
        if (opt) position.args = opt;

        var isDistanceRelative = !localOpt.absoluteDistance; // relative by default
        var isDistanceAbsoluteReverse = (localOpt.absoluteDistance && localOpt.reverseDistance); // non-reverse by default
        var isOffsetAbsolute = localOpt.absoluteOffset; // offset is non-absolute by default

        var path = this.path;
        var pathOpt = { segmentSubdivisions: this.getConnectionSubdivisions() };

        var labelPoint = new g.Point(x, y);
        var t = path.closestPointT(labelPoint, pathOpt);

        // GET DISTANCE:

        var labelDistance = path.lengthAtT(t, pathOpt);
        if (isDistanceRelative) labelDistance = (labelDistance / this.getConnectionLength()) || 0; // fix to prevent NaN for 0 length
        if (isDistanceAbsoluteReverse) labelDistance = (-1 * (this.getConnectionLength() - labelDistance)) || 1; // fix for end point (-0 => 1)

        position.distance = labelDistance;

        // GET OFFSET:
        // use absolute offset if:
        // - opt.absoluteOffset is true,
        // - opt.absoluteOffset is not true but there is no tangent

        var tangent;
        if (!isOffsetAbsolute) tangent = path.tangentAtT(t);

        var labelOffset;
        if (tangent) {
            labelOffset = tangent.pointOffset(labelPoint);

        } else {
            var closestPoint = path.pointAtT(t);
            var labelOffsetDiff = labelPoint.difference(closestPoint);
            labelOffset = { x: labelOffsetDiff.x, y: labelOffsetDiff.y };
        }

        position.offset = labelOffset;

        return position;
    }
649250
function catmullRomSpline(points, numPoints, num, strength, circular,
                          float32BufferPool) {
  circular = circular || false;
  strength = strength || 0.5;
  var out = null;
  var outLength = catmullRomSplineNumPoints(numPoints, num, circular) * 3;
  if (float32BufferPool) {
    out = float32BufferPool.request(outLength);
  } else {
    out = new Float32Array(outLength);
  }
  var index = 0;
  var delta_t = 1.0 / num;
  var m_k = vec3.create(), m_kp1 = vec3.create(); // tangents at k-1 and k+1
  var p_k = vec3.create(), p_kp1 = vec3.create(), p_kp2 = vec3.create(),
      p_kp3 = vec3.create();
  var i, j, e;

  vec3.set(p_kp1, points[0], points[1], points[2]);
  vec3.set(p_kp2, points[3], points[4], points[5]);
  if (circular) {
    vec3.set(p_k, points[points.length - 3], points[points.length - 2],
             points[points.length - 1]);
    vec3.sub(m_k, p_kp2, p_k);
    vec3.scale(m_k, m_k, strength);
  } else {
    vec3.set(p_k, points[0], points[1], points[2]);
    vec3.set(m_k, 0, 0, 0);
  }
  for (i = 1, e = numPoints - 1; i < e; ++i) {
    vec3.set(p_kp3, points[3 * (i + 1)], points[3 * (i + 1) + 1],
             points[3 * (i + 1) + 2]);
    vec3.sub(m_kp1, p_kp3, p_kp1);
    vec3.scale(m_kp1, m_kp1, strength);
    for (j = 0; j < num; ++j) {
      cubicHermiteInterpolate(out, p_kp1, m_k, p_kp2, m_kp1, delta_t * j,
                              index);
      index += 3;
    }
    vec3.copy(p_k, p_kp1);
    vec3.copy(p_kp1, p_kp2);
    vec3.copy(p_kp2, p_kp3);
    vec3.copy(m_k, m_kp1);
  }
  if (circular) {
    vec3.set(p_kp3, points[0], points[1], points[3]);
    vec3.sub(m_kp1, p_kp3, p_kp1);
    vec3.scale(m_kp1, m_kp1, strength);
  } else {
    vec3.set(m_kp1, 0, 0, 0);
  }
  for (j = 0; j < num; ++j) {
    cubicHermiteInterpolate(out, p_kp1, m_k, p_kp2, m_kp1, delta_t * j, index);
    index += 3;
  }
  if (!circular) {
    out[index] = points[3 * (numPoints - 1) + 0];
    out[index + 1] = points[3 * (numPoints - 1) + 1];
    out[index + 2] = points[3 * (numPoints - 1) + 2];
    return out;
  }
  vec3.copy(p_k, p_kp1);
  vec3.copy(p_kp1, p_kp2);
  vec3.copy(p_kp2, p_kp3);
  vec3.copy(m_k, m_kp1);
  vec3.set(p_kp3, points[3], points[4], points[5]);
  vec3.sub(m_kp1, p_kp3, p_kp1);
  vec3.scale(m_kp1, m_kp1, strength);
  for (j = 0; j < num; ++j) {
    cubicHermiteInterpolate(out, p_kp1, m_k, p_kp2, m_kp1, delta_t * j, index);
    index += 3;
  }
  return out;
}
337308
def unit_tangent(self, t=None):
        """"""
        assert self.end != self.start
        dseg = self.end - self.start
        return dseg/abs(dseg)
777515
function (shape, curve, path3D, shapePaths, scale, rotation, scaleFunction, rotateFunction, cap, custom) {
                var tangents = path3D.getTangents();
                var normals = path3D.getNormals();
                var binormals = path3D.getBinormals();
                var distances = path3D.getDistances();
                var angle = 0;
                var returnScale = function () { return scale; };
                var returnRotation = function () { return rotation; };
                var rotate = custom ? rotateFunction : returnRotation;
                var scl = custom ? scaleFunction : returnScale;
                var index = (cap === BABYLON.Mesh.NO_CAP || cap === BABYLON.Mesh.CAP_END) ? 0 : 2;
                var rotationMatrix = BABYLON.Tmp.Matrix[0];
                for (var i = 0; i < curve.length; i++) {
                    var shapePath = new Array();
                    var angleStep = rotate(i, distances[i]);
                    var scaleRatio = scl(i, distances[i]);
                    for (var p = 0; p < shape.length; p++) {
                        BABYLON.Matrix.RotationAxisToRef(tangents[i], angle, rotationMatrix);
                        var planed = ((tangents[i].scale(shape[p].z)).add(normals[i].scale(shape[p].x)).add(binormals[i].scale(shape[p].y)));
                        var rotated = shapePath[p] ? shapePath[p] : BABYLON.Vector3.Zero();
                        BABYLON.Vector3.TransformCoordinatesToRef(planed, rotationMatrix, rotated);
                        rotated.scaleInPlace(scaleRatio).addInPlace(curve[i]);
                        shapePath[p] = rotated;
                    }
                    shapePaths[index] = shapePath;
                    angle += angleStep;
                    index++;
                }
                // cap
                var capPath = function (shapePath) {
                    var pointCap = Array();
                    var barycenter = BABYLON.Vector3.Zero();
                    var i;
                    for (i = 0; i < shapePath.length; i++) {
                        barycenter.addInPlace(shapePath[i]);
                    }
                    barycenter.scaleInPlace(1.0 / shapePath.length);
                    for (i = 0; i < shapePath.length; i++) {
                        pointCap.push(barycenter);
                    }
                    return pointCap;
                };
                switch (cap) {
                    case BABYLON.Mesh.NO_CAP:
                        break;
                    case BABYLON.Mesh.CAP_START:
                        shapePaths[0] = capPath(shapePaths[2]);
                        shapePaths[1] = shapePaths[2];
                        break;
                    case BABYLON.Mesh.CAP_END:
                        shapePaths[index] = shapePaths[index - 1];
                        shapePaths[index + 1] = capPath(shapePaths[index - 1]);
                        break;
                    case BABYLON.Mesh.CAP_ALL:
                        shapePaths[0] = capPath(shapePaths[2]);
                        shapePaths[1] = shapePaths[2];
                        shapePaths[index] = shapePaths[index - 1];
                        shapePaths[index + 1] = capPath(shapePaths[index - 1]);
                        break;
                    default:
                        break;
                }
                return shapePaths;
            }
542303
def point_to_t(self, point):
        """"""

        # Single-precision floats have only 7 significant figures of
        # resolution, so test that we're within 6 sig figs.
        if np.isclose(point, self.start, rtol=0, atol=1e-6):
            return 0.0
        elif np.isclose(point, self.end, rtol=0, atol=1e-6):
            return 1.0

        # Finding the point "by hand" here is much faster than calling
        # radialrange(), see the discussion on PR #40:
        # https://github.com/mathandy/svgpathtools/pull/40#issuecomment-358134261

        p = self.poly()
        # p(t) = (p_1 * t) + p_0 = point
        # t = (point - p_0) / p_1
        t = (point - p[0]) / p[1]
        if np.isclose(t.imag, 0) and (t.real >= 0.0) and (t.real <= 1.0):
            return t.real
        return None
829410
function generateBezier (mX1, mY1, mX2, mY2) {
        var NEWTON_ITERATIONS = 4,
            NEWTON_MIN_SLOPE = 0.001,
            SUBDIVISION_PRECISION = 0.0000001,
            SUBDIVISION_MAX_ITERATIONS = 10,
            kSplineTableSize = 11,
            kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),
            float32ArraySupported = "Float32Array" in window;

        /* Must contain four arguments. */
        if (arguments.length !== 4) {
            return false;
        }

        /* Arguments must be numbers. */
        for (var i = 0; i < 4; ++i) {
            if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) {
                return false;
            }
        }

        /* X values must be in the [0, 1] range. */
        mX1 = Math.min(mX1, 1);
        mX2 = Math.min(mX2, 1);
        mX1 = Math.max(mX1, 0);
        mX2 = Math.max(mX2, 0);

        var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);

        function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
        function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
        function C (aA1)      { return 3.0 * aA1; }

        function calcBezier (aT, aA1, aA2) {
            return ((A(aA1, aA2)*aT + B(aA1, aA2))*aT + C(aA1))*aT;
        }

        function getSlope (aT, aA1, aA2) {
            return 3.0 * A(aA1, aA2)*aT*aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
        }

        function newtonRaphsonIterate (aX, aGuessT) {
            for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
                var currentSlope = getSlope(aGuessT, mX1, mX2);

                if (currentSlope === 0.0) return aGuessT;

                var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
                aGuessT -= currentX / currentSlope;
            }

            return aGuessT;
        }

        function calcSampleValues () {
            for (var i = 0; i < kSplineTableSize; ++i) {
                mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
            }
        }

        function binarySubdivide (aX, aA, aB) {
            var currentX, currentT, i = 0;

            do {
                currentT = aA + (aB - aA) / 2.0;
                currentX = calcBezier(currentT, mX1, mX2) - aX;
                if (currentX > 0.0) {
                  aB = currentT;
                } else {
                  aA = currentT;
                }
            } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);

            return currentT;
        }

        function getTForX (aX) {
            var intervalStart = 0.0,
                currentSample = 1,
                lastSample = kSplineTableSize - 1;

            for (; currentSample != lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
                intervalStart += kSampleStepSize;
            }

            --currentSample;

            var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] - mSampleValues[currentSample]),
                guessForT = intervalStart + dist * kSampleStepSize,
                initialSlope = getSlope(guessForT, mX1, mX2);

            if (initialSlope >= NEWTON_MIN_SLOPE) {
                return newtonRaphsonIterate(aX, guessForT);
            } else if (initialSlope == 0.0) {
                return guessForT;
            } else {
                return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);
            }
        }

        var _precomputed = false;

        function precompute() {
            _precomputed = true;
            if (mX1 != mY1 || mX2 != mY2) calcSampleValues();
        }

        var f = function (aX) {
            if (!_precomputed) precompute();
            if (mX1 === mY1 && mX2 === mY2) return aX;
            if (aX === 0) return 0;
            if (aX === 1) return 1;

            return calcBezier(getTForX(aX), mY1, mY2);
        };

        f.getControlPoints = function() { return [{ x: mX1, y: mY1 }, { x: mX2, y: mY2 }]; };

        var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")";
        f.toString = function () { return str; };

        return f;
    }
564861
function getLengthInternal(coordinates, radius) {
  let length = 0;
  for (let i = 0, ii = coordinates.length; i < ii - 1; ++i) {
    length += getDistance(coordinates[i], coordinates[i + 1], radius);
  }
  return length;
}
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))
1011818
def polyline(*points):
    """"""
    return Path(*[Line(points[i], points[i+1])
                  for i in range(len(points) - 1)])
607538
function smoothLine(fromX,fromY,toX,toY) {
  var radius=10,p,_translate;
  var signX=fromX>toX?-1:1,signY=fromY>toY?-1:1;
  if (Math.abs(fromY-toY)<radius*1.5 /*|| Math.abs(fromX-toX)<radius*2*/) {
    p=['M',fromX,fromY,
       'C',fromX+Math.min(Math.abs(toX-fromX)/2,radius)*signX,fromY,
       toX-(toX-fromX)/2,toY,
       toX,toY];
    _translate=function (x,y) {
      var p=this.path;
      p[1]+=x;p[2]+=y;
      p[4]+=x;p[5]+=y;
      p[6]+=x;p[7]+=y;
      p[8]+=x;p[9]+=y;
    };
  } else {
    p=[
      'M',fromX,fromY,
      'Q',fromX+radius*signX,fromY,fromX+radius*signX,fromY+radius*signY,
      'V',Math.abs(fromY-toY)<radius*2 ? fromY+radius*signY : (toY-radius*signY),
      'Q',fromX+radius*signX,toY,fromX+radius*signX*2,toY,
      'H',toX
    ];
    _translate=function (x,y) {
      var p=this.path;
      p[1]+=x;p[2]+=y;
      p[4]+=x;p[5]+=y;p[6]+=x;p[7]+=y;
      p[9]+=y;
      p[11]+=x;p[12]+=y;p[13]+=x;p[14]+=y;
      p[16]+=x;
    };
  }
  return {
    type:'path',
    path:p,
    'stroke-linecap':'butt',
    'stroke-linejoin':'round',
    'stroke':'#333',
    'stroke-width':2,
    _translate:_translate
  };
}
949794
def smoothed_path(path, maxjointsize=3, tightness=1.99, ignore_unfixable_kinks=False):
    """"""
    if len(path) == 1:
        return path

    assert path.iscontinuous()

    sharp_kinks = []
    new_path = [path[0]]
    for idx in range(len(path)):
        if idx == len(path)-1:
            if not path.isclosed():
                continue
            else:
                seg1 = new_path[0]
        else:
            seg1 = path[idx + 1]
        seg0 = new_path[-1]

        try:
            unit_tangent0 = seg0.unit_tangent(1)
            unit_tangent1 = seg1.unit_tangent(0)
            flag = False
        except ValueError:
            flag = True  # unit tangent not well-defined

        if not flag and isclose(unit_tangent0, unit_tangent1):  # joint is already smooth
            if idx != len(path)-1:
                new_path.append(seg1)
            continue
        else:
            kink_idx = (idx + 1) % len(path)  # kink at start of this seg
            if not flag and isclose(-unit_tangent0, unit_tangent1):
                # joint is sharp 180 deg (must be fixed manually)
                new_path.append(seg1)
                sharp_kinks.append(kink_idx)
            else:  # joint is not smooth, let's  smooth it.
                args = (seg0, seg1, maxjointsize, tightness)
                new_seg0, elbow_segs, new_seg1 = smoothed_joint(*args)
                new_path[-1] = new_seg0
                new_path += elbow_segs
                if idx == len(path) - 1:
                    new_path[0] = new_seg1
                else:
                    new_path.append(new_seg1)

    # If unfixable kinks were found, let the user know
    if sharp_kinks and not ignore_unfixable_kinks:
        _report_unfixable_kinks(path, sharp_kinks)

    return Path(*new_path)
333605
public float getTangentY(int vertex) {
        if (!hasTangentsAndBitangents()) {
            throw new IllegalStateException("mesh has no bitangents");
        }
        
        checkVertexIndexBounds(vertex);
        
        return m_tangents.getFloat((vertex * 3 + 1) * SIZEOF_FLOAT);
    }
852024
function d3_svg_lineMonotoneTangents(points) {
  var tangents = [],
      d,
      a,
      b,
      s,
      m = d3_svg_lineFiniteDifferences(points),
      i = -1,
      j = points.length - 1;

  // The first two steps are done by computing finite-differences:
  // 1. Compute the slopes of the secant lines between successive points.
  // 2. Initialize the tangents at every point as the average of the secants.

  // Then, for each segment…
  while (++i < j) {
    d = d3_svg_lineSlope(points[i], points[i + 1]);

    // 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set
    // mk = m{k + 1} = 0 as the spline connecting these points must be flat to
    // preserve monotonicity. Ignore step 4 and 5 for those k.

    // ε = 1e-6
    if (abs(d) < 0.000001) {
      m[i] = m[i + 1] = 0;
    } else {
      // 4. Let ak = mk / dk and bk = m{k + 1} / dk.
      a = m[i] / d;
      b = m[i + 1] / d;

      // 5. Prevent overshoot and ensure monotonicity by restricting the
      // magnitude of vector <ak, bk> to a circle of radius 3.
      s = a * a + b * b;
      if (s > 9) {
        s = d * 3 / Math.sqrt(s);
        m[i] = s * a;
        m[i + 1] = s * b;
      }
    }
  }

  // Compute the normalized tangent vector from the slopes. Note that if x is
  // not monotonic, it's possible that the slope will be infinite, so we protect
  // against NaN by setting the coordinate to zero.
  i = -1; while (++i <= j) {
    s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
    tangents.push([s || 0, m[i] * s || 0]);
  }

  return tangents;
}
226777
function getPointOnBezier(startX, startY, cpX, cpY, endX, endY, distance){
    var bestT = 0;
    var bestAccuracy = 1000;
    var stepSize = 0.001;
    for(var t = 0; t<1; t+=stepSize){
      var currentPoint = getQuadraticCurvePoint(startX, startY, cpX, cpY,
          endX, endY, t);
      var currentDistance = getDistanceBetweenPoints(startX, startY,
          currentPoint.x, currentPoint.y);
      if(Math.abs(currentDistance-distance) < bestAccuracy){
        bestAccuracy = Math.abs(currentDistance-distance);
        bestT = t;
      }
    }
    return getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, bestT);
  }
918854
def get_4pt_bezier(steps, points):
    """"""
    for i in range(steps):
        t = i / float(steps)

        xloc = (math.pow(1 - t, 3) * points[0][0] +
                3 * t * math.pow(1 - t, 2) * points[1][0] +
                3 * (1 - t) * math.pow(t, 2) * points[2][0] +
                math.pow(t, 3) * points[3][0])
        yloc = (math.pow(1 - t, 3) * points[0][1] +
                3 * t * math.pow(1 - t, 2) * points[1][1] +
                3 * (1 - t) * math.pow(t, 2) * points[2][1] +
                math.pow(t, 3) * points[3][1])

        yield (xloc, yloc)
926031
function(ratio, opt) {

            if (ratio <= 0) return 0;
            if (ratio >= 1) return 1;

            opt = opt || {};
            var precision = (opt.precision === undefined) ? this.PRECISION : opt.precision;
            var subdivisions = (opt.subdivisions === undefined) ? this.getSubdivisions({ precision: precision }) : opt.subdivisions;
            var localOpt = { precision: precision, subdivisions: subdivisions };

            var curveLength = this.length(localOpt);
            var length = curveLength * ratio;

            return this.tAtLength(length, localOpt);
        }