// Verifies that EncodedS2LaxPolygonShape behaves identically to // S2LaxPolygonShape. Also supports testing that the encoded form is identical // to the re-encoded form. private static void TestEncodedS2LaxPolygonShape(S2LaxPolygonShape original) { Encoder encoder = new(); original.Encode(encoder, CodingHint.COMPACT); var decoder = encoder.Decoder(); var(success, encoded) = EncodedS2LaxPolygonShape.Init(decoder); Assert.True(success); Assert.Equal(encoded.NumLoops, original.NumLoops); Assert.Equal(encoded.NumVertices, original.NumVertices); Assert.Equal(encoded.NumEdges(), original.NumEdges()); Assert.Equal(encoded.NumChains(), original.NumChains()); Assert.Equal(encoded.Dimension(), original.Dimension()); Assert.Equal(encoded.IsEmpty(), original.IsEmpty()); Assert.Equal(encoded.IsFull(), original.IsFull()); Assert.Equal(encoded.GetReferencePoint(), original.GetReferencePoint()); for (int i = 0; i < original.NumLoops; ++i) { Assert.Equal(encoded.NumLoopVertices(i), original.NumLoopVertices(i)); Assert.Equal(encoded.GetChain(i), original.GetChain(i)); for (int j = 0; j < original.NumLoopVertices(i); ++j) { Assert.Equal(encoded.LoopVertex(i, j), original.LoopVertex(i, j)); Assert.Equal(encoded.ChainEdge(i, j), original.ChainEdge(i, j)); } } // Now test all the edges in a random order in order to exercise the cases // involving prev_loop_. var count = original.NumEdges(); List <int> edge_ids = new(count); LinqUtils.Iota(edge_ids, 0, count); var mt = new PseudoRandom.MersenneTwister(); edge_ids = edge_ids.Shuffle(mt.genrand_N).ToList(); foreach (var e in edge_ids) { Assert.Equal(encoded.GetChainPosition(e), original.GetChainPosition(e)); Assert.Equal(encoded.GetEdge(e), original.GetEdge(e)); } // Let's also test that the encoded form can be encoded, yielding the same // bytes as the originally encoded form. Encoder reencoder = new(); encoded.Encode(reencoder, CodingHint.COMPACT); Assert.True(encoder == reencoder); }
public void Test_S2LaxPolygonShape_SingleVertexPolygon() { // S2Polygon doesn't support single-vertex loops, so we need to construct // the S2LaxPolygonShape directly. var loops = new List <List <S2Point> > { ParsePointsOrDie("0:0") }; var shape = new S2LaxPolygonShape(loops); Assert.Equal(1, shape.NumLoops); Assert.Equal(1, shape.NumVertices); Assert.Equal(1, shape.NumEdges()); Assert.Equal(1, shape.NumChains()); Assert.Equal(0, shape.GetChain(0).Start); Assert.Equal(1, shape.GetChain(0).Length); var edge = shape.GetEdge(0); Assert.Equal(loops[0][0], edge.V0); Assert.Equal(loops[0][0], edge.V1); Assert.True(edge == shape.ChainEdge(0, 0)); Assert.Equal(2, shape.Dimension()); Assert.False(shape.IsEmpty()); Assert.False(shape.IsFull()); Assert.False(shape.GetReferencePoint().Contained); TestEncodedS2LaxPolygonShape(shape); }
public void Test_S2LaxPolygonShape_SingleLoopPolygon() { // Test S2Polygon constructor. var vertices = ParsePointsOrDie("0:0, 0:1, 1:1, 1:0"); var shape = new S2LaxPolygonShape(new S2Polygon(new S2Loop(vertices))); Assert.Equal(1, shape.NumLoops); Assert.Equal(vertices.Count, shape.NumVertices); Assert.Equal(vertices.Count, shape.NumLoopVertices(0)); Assert.Equal(vertices.Count, shape.NumEdges()); Assert.Equal(1, shape.NumChains()); Assert.Equal(0, shape.GetChain(0).Start); Assert.Equal(vertices.Count, shape.GetChain(0).Length); for (int i = 0; i < vertices.Count; ++i) { Assert.Equal(vertices[i], shape.LoopVertex(0, i)); var edge = shape.GetEdge(i); Assert.Equal(vertices[i], edge.V0); Assert.Equal(vertices[(i + 1) % vertices.Count], edge.V1); Assert.Equal(edge.V0, shape.ChainEdge(0, i).V0); Assert.Equal(edge.V1, shape.ChainEdge(0, i).V1); } Assert.Equal(2, shape.Dimension()); Assert.False(shape.IsEmpty()); Assert.False(shape.IsFull()); Assert.False(shape.ContainsBruteForce(S2.Origin)); TestEncodedS2LaxPolygonShape(shape); }
public void Test_S2LaxPolygonShape_FullPolygon() { var shape = new S2LaxPolygonShape(new S2Polygon(MakeLoopOrDie("full"))); Assert.Equal(1, shape.NumLoops); Assert.Equal(0, shape.NumVertices); Assert.Equal(0, shape.NumEdges()); Assert.Equal(1, shape.NumChains()); Assert.Equal(2, shape.Dimension()); Assert.False(shape.IsEmpty()); Assert.True(shape.IsFull()); Assert.True(shape.GetReferencePoint().Contained); TestEncodedS2LaxPolygonShape(shape); }
public void Test_S2LaxPolygonShape_ManyLoopPolygon() { // Test a polygon with enough loops so that binary search is used to find // the loop containing a given edge. var loops = new List <List <S2Point> >(); for (int i = 0; i < 100; ++i) { var center = S2LatLng.FromDegrees(0, i).ToPoint(); var loop = S2Testing.MakeRegularPoints( center, S1Angle.FromDegrees(0.1), S2Testing.Random.Uniform(3)); loops.Add(loop.ToList()); } var shape = new S2LaxPolygonShape(loops); Assert.Equal(loops.Count, shape.NumLoops); int num_vertices = 0; Assert.Equal(loops.Count, shape.NumChains()); for (int i = 0; i < loops.Count; ++i) { Assert.Equal(loops[i].Count, shape.NumLoopVertices(i)); Assert.Equal(num_vertices, shape.GetChain(i).Start); Assert.Equal(loops[i].Count, shape.GetChain(i).Length); for (int j = 0; j < loops[i].Count; ++j) { Assert.Equal(loops[i][j], shape.LoopVertex(i, j)); int e = num_vertices + j; Assert.Equal(shape.GetChainPosition(e), new S2Shape.ChainPosition(i, j)); Assert.Equal(loops[i][j], shape.GetEdge(e).V0); Assert.Equal(loops[i][(j + 1) % loops[i].Count], shape.GetEdge(e).V1); } num_vertices += loops[i].Count; } Assert.Equal(num_vertices, shape.NumVertices); Assert.Equal(num_vertices, shape.NumEdges()); // Now test all the edges in a random order in order to exercise the cases // involving prev_loop_. List <(int, int, int)> edges = new(); for (int i = 0, e = 0; i < loops.Count; ++i) { for (int j = 0; j < loops[i].Count; ++j, ++e) { edges.Add((e, i, j)); } } var mt = new PseudoRandom.MersenneTwister(); edges = edges.Shuffle(mt.genrand_N).ToList(); foreach (var(e, i, j) in edges) { Assert.Equal(shape.GetChainPosition(e), new S2Shape.ChainPosition(i, j)); var v0 = loops[i][j]; var v1 = loops[i][(j + 1) % loops[i].Count]; Assert.Equal(shape.GetEdge(e), new S2Shape.Edge(v0, v1)); } TestEncodedS2LaxPolygonShape(shape); }