func()

in s2/loop.go [268:320]


func (l *Loop) Contains(o *Loop) bool {
	// For a loop A to contain the loop B, all of the following must
	// be true:
	//
	//  (1) There are no edge crossings between A and B except at vertices.
	//
	//  (2) At every vertex that is shared between A and B, the local edge
	//      ordering implies that A contains B.
	//
	//  (3) If there are no shared vertices, then A must contain a vertex of B
	//      and B must not contain a vertex of A. (An arbitrary vertex may be
	//      chosen in each case.)
	//
	// The second part of (3) is necessary to detect the case of two loops whose
	// union is the entire sphere, i.e. two loops that contains each other's
	// boundaries but not each other's interiors.
	if !l.subregionBound.Contains(o.bound) {
		return false
	}

	// Special cases to handle either loop being empty or full.
	if l.isEmptyOrFull() || o.isEmptyOrFull() {
		return l.IsFull() || o.IsEmpty()
	}

	// Check whether there are any edge crossings, and also check the loop
	// relationship at any shared vertices.
	relation := &containsRelation{}
	if hasCrossingRelation(l, o, relation) {
		return false
	}

	// There are no crossings, and if there are any shared vertices then A
	// contains B locally at each shared vertex.
	if relation.foundSharedVertex {
		return true
	}

	// Since there are no edge intersections or shared vertices, we just need to
	// test condition (3) above. We can skip this test if we discovered that A
	// contains at least one point of B while checking for edge crossings.
	if !l.ContainsPoint(o.Vertex(0)) {
		return false
	}

	// We still need to check whether (A union B) is the entire sphere.
	// Normally this check is very cheap due to the bounding box precondition.
	if (o.subregionBound.Contains(l.bound) || o.bound.Union(l.bound).IsFull()) &&
		o.ContainsPoint(l.Vertex(0)) {
		return false
	}
	return true
}