Closes last path of the MultiPathImpl with the Bezier Segment.

The start point of the Bezier is the last point of the path and the last
point of the bezier is the first point of the path.
168978
public void closePathWithBezier(Point2D controlPoint1, Point2D controlPoint2) {
		_touch();
		if (isEmptyImpl())
			throw new GeometryException(
					"Invalid call. This operation cannot be performed on an empty geometry.");

		m_bPathStarted = false;

		int pathIndex = m_paths.size() - 2;
		byte pf = m_pathFlags.read(pathIndex);
		m_pathFlags
				.write(pathIndex,
						(byte) (pf | PathFlags.enumClosed | PathFlags.enumHasNonlinearSegments));
		_initSegmentData(6);

		byte oldType = m_segmentFlags
				.read((byte) ((m_pointCount - 1) & SegmentFlags.enumSegmentMask));
		m_segmentFlags.write(m_pointCount - 1,
				(byte) (SegmentFlags.enumBezierSeg));

		int curveIndex = m_curveParamwritePoint;
		if (getSegmentDataSize(oldType) < getSegmentDataSize((byte) SegmentFlags.enumBezierSeg)) {
			m_segmentParamIndex.write(m_pointCount - 1, m_curveParamwritePoint);
			m_curveParamwritePoint += 6;
		} else {
			// there was a closing bezier curve or an arc here. We can reuse the
			// storage.
			curveIndex = m_segmentParamIndex.read(m_pointCount - 1);
		}

		double z;
		m_segmentParams.write(curveIndex, controlPoint1.x);
		m_segmentParams.write(curveIndex + 1, controlPoint1.y);
		z = 0;// TODO: calculate me.
		m_segmentParams.write(curveIndex + 2, z);

		m_segmentParams.write(curveIndex + 3, controlPoint2.x);
		m_segmentParams.write(curveIndex + 4, controlPoint2.y);
		z = 0;// TODO: calculate me.
		m_segmentParams.write(curveIndex + 5, z);
	}
1103363
static boolean linearPathIntersectsPoint_(MultiPath multipathA,
			Point2D ptB, double tolerance) {
		Point2D closest = new Point2D();
		double toleranceSq = tolerance * tolerance;
		SegmentIteratorImpl segIterA = ((MultiPathImpl) multipathA._getImpl())
				.querySegmentIterator();

		GeometryAccelerators accel = ((MultiPathImpl) multipathA._getImpl())
				._getAccelerators();

		if (accel != null) {
			QuadTreeImpl quadTreeA = accel.getQuadTree();
			if (quadTreeA != null) {
				Envelope2D env_b = new Envelope2D();
				env_b.setCoords(ptB);

				QuadTreeImpl.QuadTreeIteratorImpl qt_iter = quadTreeA
						.getIterator(env_b, tolerance);

				for (int e = qt_iter.next(); e != -1; e = qt_iter.next()) {
					segIterA.resetToVertex(quadTreeA.getElement(e));

					if (segIterA.hasNextSegment()) {
						Segment segmentA = segIterA.nextSegment();

						double t = segmentA.getClosestCoordinate(ptB, false);
						segmentA.getCoord2D(t, closest);

						if (Point2D.sqrDistance(ptB, closest) <= toleranceSq) {
							return true;
						}
					}
				}

				return false;
			}
		}
		Envelope2D env_a = new Envelope2D();

		while (segIterA.nextPath()) {
			while (segIterA.hasNextSegment()) {
				Segment segmentA = segIterA.nextSegment();
				segmentA.queryEnvelope2D(env_a);
				env_a.inflate(tolerance, tolerance);

				if (!env_a.contains(ptB)) {
					continue;
				}

				double t = segmentA.getClosestCoordinate(ptB, false);
				segmentA.getCoord2D(t, closest);

				if (Point2D.sqrDistance(ptB, closest) <= toleranceSq) {
					return true;
				}
			}
		}

		return false;
	}
274380
void clearPath(int path) {
		int first_vertex = getFirstVertex(path);
		if (first_vertex != -1) {
			// TODO: can ve do this in one shot?
			int vertex = first_vertex;
			for (int i = 0, n = getPathSize(path); i < n; i++) {
				int v = vertex;
				vertex = getNextVertex(vertex);
				freeVertex_(v);
			}
			int geometry = getGeometryFromPath(path);
			setGeometryVertexCount_(geometry, getPointCount(geometry)
					- getPathSize(path));
		}
		setPathSize_(path, 0);
	}
942884
public void bezierTo(Point2D controlPoint1, Point2D controlPoint2,
			Point2D endPoint) {
		_beforeNewSegment(1);
		setXY(m_pointCount - 1, endPoint);
		double z;
		_initSegmentData(6);
		m_pathFlags.setBits(m_pathFlags.size() - 1,
				(byte) PathFlags.enumHasNonlinearSegments);
		m_segmentParamIndex.write(m_pointCount - 2, m_curveParamwritePoint);
		m_curveParamwritePoint += 6;
		int curveIndex = m_curveParamwritePoint;
		m_segmentParams.write(curveIndex, controlPoint1.x);
		m_segmentParams.write(curveIndex + 1, controlPoint1.y);
		z = 0;// TODO: calculate me.
		m_segmentParams.write(curveIndex + 2, z);
		m_segmentParams.write(curveIndex + 3, controlPoint2.x);
		m_segmentParams.write(curveIndex + 4, controlPoint2.y);
		z = 0;// TODO: calculate me.
		m_segmentParams.write(curveIndex + 5, z);
		_finishBezierTo();
	}
692075
def start_point(self):
        
        edge = self.result.wire().val().Edges()[0]
        return edge.Vertices()[0].Center()
614257
int removePath(int path) {
		int prev = getPrevPath(path);
		int next = getNextPath(path);
		int geometry = getGeometryFromPath(path);
		if (prev != -1)
			setNextPath_(prev, next);
		else {
			setFirstPath_(geometry, next);
		}
		if (next != -1)
			setPrevPath_(next, prev);
		else {
			setLastPath_(geometry, prev);
		}

		clearPath(path);

		setGeometryPathCount_(geometry, getPathCount(geometry) - 1);
		freePath_(path);
		return next;
	}
507261
public function closePath() 
    {
        $pathsCount = count($this->paths);
        if ($pathsCount > 0) {
            $path = $this->paths[$pathsCount - 1];
            $pathCount = count($path);
            
            if ($pathCount > 2) {
                // Close path
                if ($path[0] != $path[$pathCount - 2] ||
                    $path[1] != $path[$pathCount - 1]
                ) {
                    $path[] = $path[0];
                    $path[] = $path[1];
                }

                // Begin a new path
                $this->paths[] = array($path[0], $path[1]);
            }
        }
    }
435292
def pt_on_bezier_curve(P=[(0.0, 0.0)], t=0.5):
    '''
    '''
    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(t, float)
    assert 0 <= t <= 1
    
    O = len(P) - 1 # Order of curve

    # Recurse down the orders calculating the next set of control points until
    #   there is only one left, which is the point we want.
    Q = P
    while O > 0:
        Q = [pt_between_pts(Q[l], Q[l+1], t) for l in range(O)]
        O -= 1
    
    assert len(Q) == 1
    return Q[0]
119325
def path_encloses_pt(pt, opt, path):
    """"""
    assert path.isclosed()
    intersections = Path(Line(pt, opt)).intersect(path)
    if len(intersections) % 2:
        return True
    else:
        return False
248100
function(length, opt) {

            var segments = this.segments;
            var numSegments = segments.length;
            if (numSegments === 0) return null; // if segments is an empty array

            var fromStart = true;
            if (length < 0) {
                fromStart = false; // negative lengths mean start calculation from end point
                length = -length; // absolute value
            }

            opt = opt || {};
            var precision = (opt.precision === undefined) ? this.PRECISION : opt.precision;
            var segmentSubdivisions = (opt.segmentSubdivisions === undefined) ? this.getSegmentSubdivisions({ precision: precision }) : opt.segmentSubdivisions;
            // not using localOpt

            var lastValidSegment; // visible AND differentiable (with a tangent)
            var l = 0; // length so far
            for (var i = (fromStart ? 0 : (numSegments - 1)); (fromStart ? (i < numSegments) : (i >= 0)); (fromStart ? (i++) : (i--))) {

                var segment = segments[i];
                var subdivisions = segmentSubdivisions[i];
                var d = segment.length({ precision: precision, subdivisions: subdivisions });

                if (segment.isDifferentiable()) {
                    if (length <= (l + d)) {
                        return segment.tangentAtLength(((fromStart ? 1 : -1) * (length - l)), { precision: precision, subdivisions: subdivisions });
                    }

                    lastValidSegment = segment;
                }

                l += d;
            }

            // if length requested is higher than the length of the path, return tangent of endpoint of last valid segment
            if (lastValidSegment) {
                var t = (fromStart ? 1 : 0);
                return lastValidSegment.tangentAtT(t);
            }

            // if no valid segment, return null
            return null;
        }
1086173
@Pure
	public final void toPath2D(Path2d path) {
		// loop on parts and build the path to draw
		boolean firstPoint;
		for (final PointGroup grp : groups()) {
			firstPoint = true;
			for (final Point2d pts : grp) {
				final double x = pts.getX();
				final double y = pts.getY();
				if (firstPoint) {
					path.moveTo(x, y);
					firstPoint = false;
				} else {
					path.lineTo(x, y);
				}
			}
		}
	}
1067406
def end_subsegment(self, end_time=None):
        
        if not self.context.end_subsegment(end_time):
            return

        # if segment is already close, we check if we can send entire segment
        # otherwise we check if we need to stream some subsegments
        if self.current_segment().ready_to_send():
            self._send_segment()
        else:
            self.stream_subsegments()
1191388
function(g, x, y, width, height, radius) {
        g.beginPath();
        // a
        g.moveTo(x + width / 2, y);
        // b
        g.bezierCurveTo(//
        x + width / 2 + radius / 2, y, //
        x + width / 2 + radius, y + radius / 2, //
        x + width / 2 + radius, y + radius);
        // c
        g.bezierCurveTo( //
        x + width / 2 + radius, y + radius * 2, //
        x + width / 2, y + height / 2 + radius / 3, //
        x + width / 2, y + height);
        // d
        g.bezierCurveTo(//
        x + width / 2, y + height / 2 + radius / 3, //
        x + width / 2 - radius, y + radius * 2, //
        x + width / 2 - radius, y + radius);
        // e (a)
        g.bezierCurveTo(//
        x + width / 2 - radius, y + radius / 2, //
        x + width / 2 - radius / 2, y + 0, //
        x + width / 2, y + 0);
        g.closePath();
    }
322657
private static boolean polylineTouchesMultiPoint_(Polyline polyline_a,
			MultiPoint multipoint_b, double tolerance,
			ProgressTracker progress_tracker) {
		// Quick rasterize test to see whether the the geometries are disjoint.
		if (tryRasterizedContainsOrDisjoint_(polyline_a, multipoint_b,
				tolerance, false) == Relation.disjoint) {
			return false;
		}

		SegmentIteratorImpl segIterA = ((MultiPathImpl) polyline_a._getImpl())
				.querySegmentIterator();

		Envelope2D env_a = new Envelope2D();
		Envelope2D env_b = new Envelope2D();
		Envelope2D envInter = new Envelope2D();
		polyline_a.queryEnvelope2D(env_a);
		multipoint_b.queryEnvelope2D(env_b);
		env_a.inflate(tolerance, tolerance);
		env_b.inflate(tolerance, tolerance);
		envInter.setCoords(env_a);
		envInter.intersect(env_b);

		QuadTreeImpl qtA = null;
		QuadTreeImpl quadTreeA = null;
        QuadTreeImpl quadTreePathsA = null;

		GeometryAccelerators accel = ((MultiPathImpl) (polyline_a._getImpl()))
				._getAccelerators();

		if (accel != null) {
			quadTreeA = accel.getQuadTree();
            quadTreePathsA = accel.getQuadTreeForPaths();
			if (quadTreeA == null) {
				qtA = InternalUtils.buildQuadTree(
						(MultiPathImpl) polyline_a._getImpl(), envInter);
				quadTreeA = qtA;
			}
		} else {
			qtA = InternalUtils.buildQuadTree(
					(MultiPathImpl) polyline_a._getImpl(), envInter);
			quadTreeA = qtA;
		}

		QuadTreeImpl.QuadTreeIteratorImpl qtIterA = quadTreeA.getIterator();

        QuadTreeImpl.QuadTreeIteratorImpl qtIterPathsA = null;
        if (quadTreePathsA != null)
            qtIterPathsA = quadTreePathsA.getIterator();

		Point2D ptB = new Point2D(), closest = new Point2D();
		boolean b_intersects = false;
		double toleranceSq = tolerance * tolerance;

		AttributeStreamOfInt8 intersects = new AttributeStreamOfInt8(
				multipoint_b.getPointCount());
		for (int i = 0; i < multipoint_b.getPointCount(); i++) {
			intersects.write(i, (byte) 0);
		}

		for (int i = 0; i < multipoint_b.getPointCount(); i++) {
			multipoint_b.getXY(i, ptB);

			if (!envInter.contains(ptB)) {
				continue;
			}

			env_b.setCoords(ptB.x, ptB.y, ptB.x, ptB.y);

            if (qtIterPathsA != null) {
                qtIterPathsA.resetIterator(env_b, tolerance);

                if (qtIterPathsA.next() == -1)
                    continue;
            }

			qtIterA.resetIterator(env_b, tolerance);

			for (int elementHandleA = qtIterA.next(); elementHandleA != -1; elementHandleA = qtIterA
					.next()) {
				int vertex_a = quadTreeA.getElement(elementHandleA);
				segIterA.resetToVertex(vertex_a);

				Segment segmentA = segIterA.nextSegment();
				double t = segmentA.getClosestCoordinate(ptB, false);
				segmentA.getCoord2D(t, closest);

				if (Point2D.sqrDistance(ptB, closest) <= toleranceSq) {
					intersects.write(i, (byte) 1);
					b_intersects = true;
					break;
				}
			}
		}

		if (!b_intersects) {
			return false;
		}

		MultiPoint boundary_a = (MultiPoint) (polyline_a.getBoundary());
		MultiPoint multipoint_b_inter = new MultiPoint();
		Point2D pt = new Point2D();

		for (int i = 0; i < multipoint_b.getPointCount(); i++) {
			if (intersects.read(i) == 0) {
				continue;
			}

			multipoint_b.getXY(i, pt);
			multipoint_b_inter.add(pt.x, pt.y);
		}

		return multiPointContainsMultiPointBrute_(boundary_a,
				multipoint_b_inter, tolerance);
	}
401587
public void startPath(double x, double y) {
		Point2D endPoint = new Point2D();
		endPoint.x = x;
		endPoint.y = y;
		startPath(endPoint);
	}
1022910
public String getLastPathSegment() {
        if (StringUtils.isBlank(path)) {
            return StringUtils.EMPTY;
        }
        String segment = path;
        segment = StringUtils.substringAfterLast(segment, "/");
        return segment;
    }
324513
function() {

            var segments = this.segments;
            var numSegments = segments.length;
            if (numSegments === 0) return null; // if segments is an empty array

            var bbox;
            for (var i = 0; i < numSegments; i++) {

                var segment = segments[i];
                if (segment.isVisible) {
                    var segmentBBox = segment.bbox();
                    bbox = bbox ? bbox.union(segmentBBox) : segmentBBox;
                }
            }

            if (bbox) return bbox;

            // if the path has only invisible elements, return end point of last segment
            var lastSegment = segments[numSegments - 1];
            return new Rect(lastSegment.end.x, lastSegment.end.y, 0, 0);
        }