// Ring will smart clip a ring to the boundary. This may result multiple rings so
// a multipolygon is possible. Rings that are NOT closed AND have an endpoint in
// the bound will be implicitly closed.
486116
func Ring(box orb.Bound, r orb.Ring, o orb.Orientation) orb.MultiPolygon {
	if len(r) == 0 {
		return nil
	}

	open, closed := clipRings(box, []orb.Ring{r})
	if len(open) == 0 {
		// nothing was clipped
		if len(closed) == 0 {
			return nil // everything outside bound
		}

		return orb.MultiPolygon{{r}} // everything inside bound
	}

	// in a well defined ring there will be no closed sections
	return smartWrap(box, open, o)
}
132739
func (b *Builder) Ring() *Ring {
	ring := &Ring{
		nodes:                    make([]*Node, len(b.nodes)),
		groups:                   make([]*Group, len(b.groups)),
		nodeToGroup:              make([]int, len(b.nodes)),
		groupToGroup:             make([]int, len(b.groups)),
		replicaToPartitionToNode: make([][]lowring.Node, len(b.ring.ReplicaToPartitionToNode)),
		rebalanced:               b.ring.Rebalanced,
	}
	for i, n := range b.nodes {
		ring.nodes[i] = &Node{
			ring:     ring,
			index:    i,
			info:     n.info,
			capacity: b.ring.NodeToCapacity[i],
		}
	}
	for i, g := range b.groups {
		ring.groups[i] = &Group{
			ring:  ring,
			index: i,
			info:  g.info,
		}
	}
	copy(ring.nodeToGroup, b.ring.NodeToGroup)
	copy(ring.groupToGroup, b.ring.GroupToGroup)
	replicaCount := len(b.ring.ReplicaToPartitionToNode)
	partitionCount := len(b.ring.ReplicaToPartitionToNode[0])
	for replica := 0; replica < replicaCount; replica++ {
		ring.replicaToPartitionToNode[replica] = make([]lowring.Node, partitionCount)
		copy(ring.replicaToPartitionToNode[replica], b.ring.ReplicaToPartitionToNode[replica])
	}
	return ring
}
1346827
func (as ArraySpec) Ring2(val Input) Input {
	return as.proc(func(i Input) Input {
		return i.Ring2(val)
	})
}
449326
func (mp MultiPoint) Bound() Bound {
	if len(mp) == 0 {
		return emptyBound
	}

	b := Bound{mp[0], mp[0]}
	for _, p := range mp {
		b = b.Extend(p)
	}

	return b
}
865104
func (s *VisvalingamSimplifier) Polygon(p orb.Polygon) orb.Polygon {
	return polygon(s, p)
}
582913
func (b Bound) Extend(point Point) Bound {
	// already included, no big deal
	if b.Contains(point) {
		return b
	}

	return Bound{
		Min: Point{
			math.Min(b.Min[0], point[0]),
			math.Min(b.Min[1], point[1]),
		},
		Max: Point{
			math.Max(b.Max[0], point[0]),
			math.Max(b.Max[1], point[1]),
		},
	}
}
708573
func Boundary(listener func(*vecty.Event)) *vecty.EventListener {
	return &vecty.EventListener{Name: "boundary", Listener: listener}
}
1354078
func (s *RadialSimplifier) Polygon(p orb.Polygon) orb.Polygon {
	return polygon(s, p)
}
96057
func NewRing(initialSet Iterable, windowSize int) *Ring {
	if windowSize < 1 {
		windowSize = 1
	}
	vc := &Ring{
		buckets: make([]*Bucket, windowSize),
		power:   NewTrimSet(),
		size:    windowSize,
	}
	for i := 0; i < windowSize; i++ {
		vc.buckets[i] = NewBucket()
	}
	if initialSet != nil {
		vc.populated = 1
		vc.buckets[0] = NewBucket(initialSet)
	}
	return vc
}
130985
func (r *Ring) mod(p int) int {
	return p % len(r.buff)
}
287126
func (c Circle) Intersect(d Circle) Circle {
	// Check if one of the circles encompasses the other; if so, return that one
	biggerC := maxCircle(c.Norm(), d.Norm())
	smallerC := minCircle(c.Norm(), d.Norm())

	if biggerC.Radius >= biggerC.Center.To(smallerC.Center).Len()+smallerC.Radius {
		return biggerC
	}

	// Calculate the midpoint between the two radii
	// Distance between centers
	dist := c.Center.To(d.Center).Len()
	// Difference between radii
	diff := dist - (c.Radius + d.Radius)
	// Distance from c.Center to the weighted midpoint
	distToMidpoint := c.Radius + 0.5*diff
	// Weighted midpoint
	center := Lerp(c.Center, d.Center, distToMidpoint/dist)

	// No need to calculate radius if the circles do not overlap
	if c.Center.To(d.Center).Len() >= c.Radius+d.Radius {
		return C(center, 0)
	}

	radius := c.Center.To(d.Center).Len() - (c.Radius + d.Radius)

	return Circle{
		Center: center,
		Radius: math.Abs(radius),
	}
}
1237738
func EncodeMultiPolygon(mp *geom.MultiPolygon) kml.Element {
	polygons := make([]kml.Element, mp.NumPolygons())
	flatCoords := mp.FlatCoords()
	endss := mp.Endss()
	stride := mp.Stride()
	d := dim(mp.Layout())
	offset := 0
	for i, ends := range endss {
		boundaries := make([]kml.Element, len(ends))
		for j, end := range ends {
			linearRing := kml.LinearRing(kml.CoordinatesFlat(flatCoords, offset, end, stride, d))
			if j == 0 {
				boundaries[j] = kml.OuterBoundaryIs(linearRing)
			} else {
				boundaries[j] = kml.InnerBoundaryIs(linearRing)
			}
			offset = end
		}
		polygons[i] = kml.Polygon(boundaries...)
	}
	return kml.MultiGeometry(polygons...)
}
670718
func (b *Bounds) Polygon() *Polygon {
	if b.IsEmpty() {
		return NewPolygonFlat(XY, nil, nil)
	}
	x1, y1 := b.min[0], b.min[1]
	x2, y2 := b.max[0], b.max[1]
	flatCoords := []float64{
		x1, y1,
		x1, y2,
		x2, y2,
		x2, y1,
		x1, y1,
	}
	return NewPolygonFlat(XY, flatCoords, []int{len(flatCoords)})
}
590364
func (g *MultiPolygon) Polygon(i int) *Polygon {
	offset := 0
	if i > 0 {
		ends := g.endss[i-1]
		offset = ends[len(ends)-1]
	}
	ends := make([]int, len(g.endss[i]))
	if offset == 0 {
		copy(ends, g.endss[i])
	} else {
		for j, end := range g.endss[i] {
			ends[j] = end - offset
		}
	}
	return NewPolygonFlat(g.layout, g.flatCoords[offset:g.endss[i][len(g.endss[i])-1]], ends)
}
139362
func (p *Polygon) Intersects(o *Polygon) bool {
	// If both polygons have one loop, use the more efficient Loop method.
	// Note that Loop Intersects does its own bounding rectangle check.
	if len(p.loops) == 1 && len(o.loops) == 1 {
		return p.loops[0].Intersects(o.loops[0])
	}

	// Otherwise if neither polygon has holes, we can still use the more
	// efficient Loop.Intersects method. The polygons intersect if and
	// only if some pair of loop regions intersect.
	if !p.bound.Intersects(o.bound) {
		return false
	}

	if !p.hasHoles && !o.hasHoles {
		for _, l := range o.loops {
			if p.anyLoopIntersects(l) {
				return true
			}
		}
		return false
	}

	// Polygon A is disjoint from B if A excludes the entire boundary of B and B
	// excludes all shell boundaries of A. (It can be shown that B must then
	// exclude the entire boundary of A.) The first call below returns false if
	// the boundaries cross, therefore the second call does not need to check
	// for crossing edges.
	return !p.excludesBoundary(o) || !o.excludesNonCrossingShells(p)
}
1036434
func (r Ring) Orientation() Orientation {
	area := 0.0

	// This is a fast planar area computation, which is okay for this use.
	// implicitly move everything to near the origin to help with roundoff
	offsetX := r[0][0]
	offsetY := r[0][1]
	for i := 1; i < len(r)-1; i++ {
		area += (r[i][0]-offsetX)*(r[i+1][1]-offsetY) -
			(r[i+1][0]-offsetX)*(r[i][1]-offsetY)
	}

	if area > 0 {
		return CCW
	}

	if area < 0 {
		return CW
	}

	// degenerate case, no area
	return 0
}
781729
func (bb BoundingBox) Geometry() interface{} {
	var result interface{}
	switch len(bb) {
	case 4:
		if (bb[0] == bb[2]) && (bb[1] == bb[3]) {
			result = NewPoint(bb[0:2])
		} else {
			coordinates := make([][][]float64, 1)
			coordinates[0] = make([][]float64, 5)
			coordinates[0][0] = make([]float64, 2)
			coordinates[0][0][0] = bb[0]
			coordinates[0][0][1] = bb[1]
			coordinates[0][1] = make([]float64, 2)
			coordinates[0][1][0] = bb[2]
			coordinates[0][1][1] = bb[1]
			coordinates[0][2] = make([]float64, 2)
			coordinates[0][2][0] = bb[2]
			coordinates[0][2][1] = bb[3]
			coordinates[0][3] = make([]float64, 2)
			coordinates[0][3][0] = bb[0]
			coordinates[0][3][1] = bb[3]
			coordinates[0][4] = make([]float64, 2)
			coordinates[0][4][0] = bb[0]
			coordinates[0][4][1] = bb[1]
			result = NewPolygon(coordinates)
		}
	}
	return result
}