1 // Copyright 2013 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS-IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 
16 // Author: ericv@google.com (Eric Veach)
17 
18 #include "s2/s2lax_loop_shape.h"
19 
20 #include <vector>
21 
22 #include <gtest/gtest.h>
23 #include "s2/s2loop.h"
24 #include "s2/s2shapeutil_contains_brute_force.h"
25 #include "s2/s2text_format.h"
26 
27 using std::vector;
28 
TEST(S2LaxLoopShape,EmptyLoop)29 TEST(S2LaxLoopShape, EmptyLoop) {
30   // Test S2Loop constructor.
31   S2LaxLoopShape shape;
32   shape.Init(S2Loop(S2Loop::kEmpty()));
33   EXPECT_EQ(0, shape.num_vertices());
34   EXPECT_EQ(0, shape.num_edges());
35   EXPECT_EQ(0, shape.num_chains());
36   EXPECT_EQ(2, shape.dimension());
37   EXPECT_TRUE(shape.is_empty());
38   EXPECT_FALSE(shape.is_full());
39   EXPECT_FALSE(shape.GetReferencePoint().contained);
40 }
41 
TEST(S2LaxLoopShape,NonEmptyLoop)42 TEST(S2LaxLoopShape, NonEmptyLoop) {
43   // Test vector<S2Point> constructor.
44   vector<S2Point> vertices = s2textformat::ParsePoints("0:0, 0:1, 1:1, 1:0");
45   S2LaxLoopShape shape(vertices);
46   EXPECT_EQ(vertices.size(), shape.num_vertices());
47   EXPECT_EQ(vertices.size(), shape.num_edges());
48   EXPECT_EQ(1, shape.num_chains());
49   EXPECT_EQ(0, shape.chain(0).start);
50   EXPECT_EQ(vertices.size(), shape.chain(0).length);
51   for (int i = 0; i < vertices.size(); ++i) {
52     EXPECT_EQ(vertices[i], shape.vertex(i));
53     auto edge = shape.edge(i);
54     EXPECT_EQ(vertices[i], edge.v0);
55     EXPECT_EQ(vertices[(i + 1) % vertices.size()], edge.v1);
56   }
57   EXPECT_EQ(2, shape.dimension());
58   EXPECT_FALSE(shape.is_empty());
59   EXPECT_FALSE(shape.is_full());
60   EXPECT_FALSE(shape.GetReferencePoint().contained);
61 }
62 
TEST(S2LaxClosedPolylineShape,NoInterior)63 TEST(S2LaxClosedPolylineShape, NoInterior) {
64   vector<S2Point> vertices = s2textformat::ParsePoints("0:0, 0:1, 1:1, 1:0");
65   S2LaxClosedPolylineShape shape(vertices);
66   EXPECT_EQ(1, shape.dimension());
67   EXPECT_FALSE(shape.is_empty());
68   EXPECT_FALSE(shape.is_full());
69   EXPECT_FALSE(shape.GetReferencePoint().contained);
70 }
71 
TEST(S2VertexIdLaxLoopShape,EmptyLoop)72 TEST(S2VertexIdLaxLoopShape, EmptyLoop) {
73   S2VertexIdLaxLoopShape shape(vector<int32>(), nullptr);
74   EXPECT_EQ(0, shape.num_edges());
75   EXPECT_EQ(0, shape.num_vertices());
76   EXPECT_EQ(0, shape.num_chains());
77   EXPECT_EQ(2, shape.dimension());
78   EXPECT_TRUE(shape.is_empty());
79   EXPECT_FALSE(shape.is_full());
80   EXPECT_FALSE(shape.GetReferencePoint().contained);
81 }
82 
TEST(S2VertexIdLaxLoopShape,InvertedLoop)83 TEST(S2VertexIdLaxLoopShape, InvertedLoop) {
84   vector<S2Point> vertex_array =
85       s2textformat::ParsePoints("0:0, 0:1, 1:1, 1:0");
86   vector<int32> vertex_ids { 0, 3, 2, 1 };  // Inverted.
87   S2VertexIdLaxLoopShape shape(vertex_ids, &vertex_array[0]);
88   EXPECT_EQ(4, shape.num_edges());
89   EXPECT_EQ(4, shape.num_vertices());
90   EXPECT_EQ(1, shape.num_chains());
91   EXPECT_EQ(0, shape.chain(0).start);
92   EXPECT_EQ(4, shape.chain(0).length);
93   EXPECT_EQ(&vertex_array[0], &shape.vertex(0));
94   EXPECT_EQ(&vertex_array[3], &shape.vertex(1));
95   EXPECT_EQ(&vertex_array[2], &shape.vertex(2));
96   EXPECT_EQ(&vertex_array[1], &shape.vertex(3));
97   EXPECT_EQ(2, shape.dimension());
98   EXPECT_FALSE(shape.is_empty());
99   EXPECT_FALSE(shape.is_full());
100   EXPECT_TRUE(s2shapeutil::ContainsBruteForce(shape, S2::Origin()));
101 }
102