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 // Original Author: ericv@google.com (Eric Veach)
17 // Converted to D:  madric@gmail.com (Vijay Nayar)
18 
19 module s2.s2lax_polyline_shape;
20 
21 import s2.s2polyline;
22 import s2.s2shape;
23 import s2.logger;
24 import s2.s2point;
25 
26 import std.algorithm;
27 
28 /**
29  * S2LaxPolylineShape represents a polyline.  It is similar to
30  * S2Polyline::Shape except that duplicate vertices are allowed, and the
31  * representation is slightly more compact.
32  *
33  * Polylines may have any number of vertices, but note that polylines with
34  * fewer than 2 vertices do not define any edges.  (To create a polyline
35  * consisting of a single degenerate edge, either repeat the same vertex twice
36  * or use S2LaxClosedPolylineShape defined in s2_lax_loop_shape.h.)
37  */
38 class S2LaxPolylineShape : S2Shape {
39 public:
40   // Constructs an empty polyline.
41   this() { }
42 
43   // Constructs an S2LaxPolylineShape with the given vertices.
44   this(S2Point[] vertices) {
45     init(vertices);
46   }
47 
48   // Constructs an S2LaxPolylineShape from the given S2Polyline, by copying
49   // its data.
50   this(in S2Polyline polyline) {
51     init(polyline);
52   }
53 
54   // Initializes an S2LaxPolylineShape with the given vertices.
55   void init(S2Point[] vertices) {
56     if (vertices.length == 1)
57       logger.logWarn("s2shapeutil::S2LaxPolylineShape with one vertex has no edges");
58     _vertices = vertices;
59   }
60 
61   // Initializes an S2LaxPolylineShape from the given S2Polyline, by copying
62   // its data.
63   void init(in S2Polyline polyline) {
64     if (polyline.vertices().length == 1)
65         logger.logWarn("s2shapeutil::S2LaxPolylineShape with one vertex has no edges");
66     _vertices = polyline.vertices().dup;
67   }
68 
69   int numVertices() const {
70     return cast(int) _vertices.length;
71   }
72 
73   const(S2Point) vertex(int i) const {
74     return _vertices[i];
75   }
76 
77   const(S2Point[]) vertices() const {
78     return _vertices;
79   }
80 
81   // S2Shape interface:
82   final override
83   int numEdges() const {
84     return max(0, numVertices() - 1);
85   }
86 
87   final override
88   Edge edge(int e) const
89   in {
90     assert(e < numEdges());
91   } do {
92     return Edge(_vertices[e], _vertices[e + 1]);
93   }
94 
95   final override
96   int dimension() const {
97     return 1;
98   }
99 
100   final override
101   ReferencePoint getReferencePoint() const {
102     return ReferencePoint(false);
103   }
104 
105   final override
106   int numChains() const {
107     return min(1, numEdges());
108   }
109 
110   final override
111   Chain chain(int i) const {
112     return Chain(0, numEdges());
113   }
114 
115   final override
116   Edge chainEdge(int i, int j) const
117   in {
118     assert(i == 0);
119     assert(j < numEdges());
120   } do {
121     return Edge(_vertices[j], _vertices[j + 1]);
122   }
123 
124   final override
125   ChainPosition chainPosition(int e) const {
126     return ChainPosition(0, e);
127   }
128 
129  private:
130   // For clients that have many small polylines, we save some memory by
131   // representing the vertices as an array rather than using std::vector.
132   S2Point[] _vertices;
133 }