1 module s2.s2wedge_relations; 2 3 // Copyright 2005 Google Inc. All Rights Reserved. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS-IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 // Original author: ericv@google.com (Eric Veach) 18 // Converted to D: madric@gmail.com (Vijay Nayar) 19 20 // Defines functions for determining the relationship between two angles 21 // ("wedges") that share a common vertex. 22 23 import s2.s2point; 24 import s2.s2predicates : orderedCCW; 25 26 // Given an edge chain (x0, x1, x2), the wedge at x1 is the region to the 27 // left of the edges. More precisely, it is the set of all rays from x1x0 28 // (inclusive) to x1x2 (exclusive) in the *clockwise* direction. 29 // 30 // The following functions compare two *non-empty* wedges that share the 31 // same middle vertex: A=(a0, ab1, a2) and B=(b0, ab1, b2). 32 33 // Detailed relation from one wedge A to another wedge B. 34 enum WedgeRelation { 35 WEDGE_EQUALS, // A and B are equal. 36 WEDGE_PROPERLY_CONTAINS, // A is a strict superset of B. 37 WEDGE_IS_PROPERLY_CONTAINED, // A is a strict subset of B. 38 WEDGE_PROPERLY_OVERLAPS, // A-B, B-A, and A intersect B are non-empty. 39 WEDGE_IS_DISJOINT, // A and B are disjoint. 40 } 41 42 // Returns the relation from wedge A to B. 43 // REQUIRES: A and B are non-empty. 44 WedgeRelation getWedgeRelation( 45 in S2Point a0, in S2Point ab1, in S2Point a2, in S2Point b0, in S2Point b2) { 46 // There are 6 possible edge orderings at a shared vertex (all 47 // of these orderings are circular, i.e. abcd == bcda): 48 // 49 // (1) a2 b2 b0 a0: A contains B 50 // (2) a2 a0 b0 b2: B contains A 51 // (3) a2 a0 b2 b0: A and B are disjoint 52 // (4) a2 b0 a0 b2: A and B intersect in one wedge 53 // (5) a2 b2 a0 b0: A and B intersect in one wedge 54 // (6) a2 b0 b2 a0: A and B intersect in two wedges 55 // 56 // We do not distinguish between 4, 5, and 6. 57 // We pay extra attention when some of the edges overlap. When edges 58 // overlap, several of these orderings can be satisfied, and we take 59 // the most specific. 60 if (a0 == b0 && a2 == b2) return WedgeRelation.WEDGE_EQUALS; 61 62 if (orderedCCW(a0, a2, b2, ab1)) { 63 // The cases with this vertex ordering are 1, 5, and 6, 64 // although case 2 is also possible if a2 == b2. 65 if (orderedCCW(b2, b0, a0, ab1)) return WedgeRelation.WEDGE_PROPERLY_CONTAINS; 66 67 // We are in case 5 or 6, or case 2 if a2 == b2. 68 return (a2 == b2) 69 ? WedgeRelation.WEDGE_IS_PROPERLY_CONTAINED : WedgeRelation.WEDGE_PROPERLY_OVERLAPS; 70 } 71 72 // We are in case 2, 3, or 4. 73 if (orderedCCW(a0, b0, b2, ab1)) return WedgeRelation.WEDGE_IS_PROPERLY_CONTAINED; 74 return orderedCCW(a0, b0, a2, ab1) 75 ? WedgeRelation.WEDGE_IS_DISJOINT : WedgeRelation.WEDGE_PROPERLY_OVERLAPS; 76 } 77 78 // Returns true if wedge A contains wedge B. Equivalent to but faster than 79 // GetWedgeRelation() == WEDGE_PROPERLY_CONTAINS || WEDGE_EQUALS. 80 // REQUIRES: A and B are non-empty. 81 bool wedgeContains( 82 in S2Point a0, in S2Point ab1, in S2Point a2, in S2Point b0, in S2Point b2) { 83 // For A to contain B (where each loop interior is defined to be its left 84 // side), the CCW edge order around ab1 must be a2 b2 b0 a0. We split 85 // this test into two parts that test three vertices each. 86 return (orderedCCW(a2, b2, b0, ab1) && orderedCCW(b0, a0, a2, ab1)); 87 } 88 89 // Returns true if wedge A intersects wedge B. Equivalent to but faster 90 // than GetWedgeRelation() != WEDGE_IS_DISJOINT. 91 // REQUIRES: A and B are non-empty. 92 bool wedgeIntersects( 93 in S2Point a0, in S2Point ab1, in S2Point a2, in S2Point b0, in S2Point b2) { 94 // For A not to intersect B (where each loop interior is defined to be 95 // its left side), the CCW edge order around ab1 must be a0 b2 b0 a2. 96 // Note that it's important to write these conditions as negatives 97 // (!OrderedCCW(a,b,c,o) rather than Ordered(c,b,a,o)) to get correct 98 // results when two vertices are the same. 99 return !(orderedCCW(a0, b2, b0, ab1) && orderedCCW(b0, a2, a0, ab1)); 100 }