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 }