@@ -7,7 +7,8 @@ use algorithm::map_coords::MapCoords;
7
7
// origin can be an arbitrary point, pass &Point::new(0., 0.)
8
8
// for the actual origin
9
9
fn rotation_matrix < T > ( angle : T , origin : & Point < T > , points : & [ Point < T > ] ) -> Vec < Point < T > >
10
- where T : Float
10
+ where
11
+ T : Float ,
11
12
{
12
13
let cos_theta = angle. to_radians ( ) . cos ( ) ;
13
14
let sin_theta = angle. to_radians ( ) . sin ( ) ;
@@ -16,11 +17,13 @@ fn rotation_matrix<T>(angle: T, origin: &Point<T>, points: &[Point<T>]) -> Vec<P
16
17
points
17
18
. iter ( )
18
19
. map ( |point| {
19
- let x = point. x ( ) - x0;
20
- let y = point. y ( ) - y0;
21
- Point :: new ( x * cos_theta - y * sin_theta + x0,
22
- x * sin_theta + y * cos_theta + y0)
23
- } )
20
+ let x = point. x ( ) - x0;
21
+ let y = point. y ( ) - y0;
22
+ Point :: new (
23
+ x * cos_theta - y * sin_theta + x0,
24
+ x * sin_theta + y * cos_theta + y0,
25
+ )
26
+ } )
24
27
. collect :: < Vec < _ > > ( )
25
28
}
26
29
@@ -46,7 +49,9 @@ pub trait Rotate<T> {
46
49
/// let correct_ls = LineString(correct);
47
50
/// assert_eq!(rotated, correct_ls);
48
51
/// ```
49
- fn rotate ( & self , angle : T ) -> Self where T : Float ;
52
+ fn rotate ( & self , angle : T ) -> Self
53
+ where
54
+ T : Float ;
50
55
}
51
56
52
57
pub trait RotatePoint < T > {
@@ -71,12 +76,15 @@ pub trait RotatePoint<T> {
71
76
/// let correct_ls = LineString(correct);
72
77
/// assert_eq!(rotated, correct_ls);
73
78
/// ```
74
- fn rotate_around_point ( & self , angle : T , point : & Point < T > ) -> Self where T : Float ;
79
+ fn rotate_around_point ( & self , angle : T , point : & Point < T > ) -> Self
80
+ where
81
+ T : Float ;
75
82
}
76
83
77
84
impl < T , G > RotatePoint < T > for G
78
- where T : Float ,
79
- G : MapCoords < T , T , Output =G > ,
85
+ where
86
+ T : Float ,
87
+ G : MapCoords < T , T , Output = G > ,
80
88
{
81
89
fn rotate_around_point ( & self , angle : T , point : & Point < T > ) -> Self {
82
90
let cos_theta = angle. to_radians ( ) . cos ( ) ;
@@ -86,14 +94,17 @@ impl<T, G> RotatePoint<T> for G
86
94
self . map_coords ( & |& ( x, y) | {
87
95
let x = x - x0;
88
96
let y = y - y0;
89
- ( x * cos_theta - y * sin_theta + x0,
90
- x * sin_theta + y * cos_theta + y0)
97
+ (
98
+ x * cos_theta - y * sin_theta + x0,
99
+ x * sin_theta + y * cos_theta + y0,
100
+ )
91
101
} )
92
102
}
93
103
}
94
104
95
105
impl < T > Rotate < T > for Point < T >
96
- where T : Float
106
+ where
107
+ T : Float ,
97
108
{
98
109
/// Rotate the Point about itself by the given number of degrees
99
110
/// This operation leaves the point coordinates unchanged
@@ -103,7 +114,8 @@ impl<T> Rotate<T> for Point<T>
103
114
}
104
115
105
116
impl < T > Rotate < T > for Line < T >
106
- where T : Float
117
+ where
118
+ T : Float ,
107
119
{
108
120
fn rotate ( & self , angle : T ) -> Self {
109
121
let pts = vec ! [ self . start, self . end] ;
@@ -113,7 +125,8 @@ impl<T> Rotate<T> for Line<T>
113
125
}
114
126
115
127
impl < T > Rotate < T > for LineString < T >
116
- where T : Float
128
+ where
129
+ T : Float ,
117
130
{
118
131
/// Rotate the LineString about its centroid by the given number of degrees
119
132
fn rotate ( & self , angle : T ) -> Self {
@@ -122,7 +135,8 @@ impl<T> Rotate<T> for LineString<T>
122
135
}
123
136
124
137
impl < T > Rotate < T > for Polygon < T >
125
- where T : Float + FromPrimitive
138
+ where
139
+ T : Float + FromPrimitive ,
126
140
{
127
141
/// Rotate the Polygon about its centroid by the given number of degrees
128
142
fn rotate ( & self , angle : T ) -> Self {
@@ -131,16 +145,21 @@ impl<T> Rotate<T> for Polygon<T>
131
145
false => self . exterior . centroid ( ) . unwrap ( ) ,
132
146
true => self . centroid ( ) . unwrap ( ) ,
133
147
} ;
134
- Polygon :: new ( LineString ( rotation_matrix ( angle, & centroid, & self . exterior . 0 ) ) ,
135
- self . interiors
136
- . iter ( )
137
- . map ( |ring| LineString ( rotation_matrix ( angle, & centroid, & ring. 0 ) ) )
138
- . collect ( ) )
148
+ Polygon :: new (
149
+ LineString ( rotation_matrix ( angle, & centroid, & self . exterior . 0 ) ) ,
150
+ self . interiors
151
+ . iter ( )
152
+ . map ( |ring| {
153
+ LineString ( rotation_matrix ( angle, & centroid, & ring. 0 ) )
154
+ } )
155
+ . collect ( ) ,
156
+ )
139
157
}
140
158
}
141
159
142
160
impl < T > Rotate < T > for MultiPolygon < T >
143
- where T : Float + FromPrimitive
161
+ where
162
+ T : Float + FromPrimitive ,
144
163
{
145
164
/// Rotate the contained Polygons about their centroids by the given number of degrees
146
165
fn rotate ( & self , angle : T ) -> Self {
@@ -149,7 +168,8 @@ impl<T> Rotate<T> for MultiPolygon<T>
149
168
}
150
169
151
170
impl < T > Rotate < T > for MultiLineString < T >
152
- where T : Float + FromPrimitive
171
+ where
172
+ T : Float + FromPrimitive ,
153
173
{
154
174
/// Rotate the contained LineStrings about their centroids by the given number of degrees
155
175
fn rotate ( & self , angle : T ) -> Self {
@@ -158,7 +178,8 @@ impl<T> Rotate<T> for MultiLineString<T>
158
178
}
159
179
160
180
impl < T > Rotate < T > for MultiPoint < T >
161
- where T : Float + FromPrimitive
181
+ where
182
+ T : Float + FromPrimitive ,
162
183
{
163
184
/// Rotate the contained Points about their centroids by the given number of degrees
164
185
fn rotate ( & self , angle : T ) -> Self {
@@ -195,74 +216,97 @@ mod test {
195
216
}
196
217
#[ test]
197
218
fn test_rotate_polygon ( ) {
198
- let points_raw = vec ! [ ( 5. , 1. ) , ( 4. , 2. ) , ( 4. , 3. ) , ( 5. , 4. ) , ( 6. , 4. ) , ( 7. , 3. ) ,
199
- ( 7. , 2. ) , ( 6. , 1. ) , ( 5. , 1. ) ] ;
219
+ let points_raw = vec ! [
220
+ ( 5. , 1. ) ,
221
+ ( 4. , 2. ) ,
222
+ ( 4. , 3. ) ,
223
+ ( 5. , 4. ) ,
224
+ ( 6. , 4. ) ,
225
+ ( 7. , 3. ) ,
226
+ ( 7. , 2. ) ,
227
+ ( 6. , 1. ) ,
228
+ ( 5. , 1. ) ,
229
+ ] ;
200
230
let points = points_raw
201
231
. iter ( )
202
232
. map ( |e| Point :: new ( e. 0 , e. 1 ) )
203
233
. collect :: < Vec < _ > > ( ) ;
204
234
let poly1 = Polygon :: new ( LineString ( points) , vec ! [ ] ) ;
205
235
let rotated = poly1. rotate ( -15.0 ) ;
206
- let correct_outside = vec ! [ ( 4.628808519201685 , 1.1805207831176578 ) ,
207
- ( 3.921701738015137 , 2.405265654509247 ) ,
208
- ( 4.180520783117657 , 3.3711914807983154 ) ,
209
- ( 5.405265654509247 , 4.0782982619848624 ) ,
210
- ( 6.371191480798315 , 3.819479216882342 ) ,
211
- ( 7.0782982619848624 , 2.594734345490753 ) ,
212
- ( 6.819479216882343 , 1.6288085192016848 ) ,
213
- ( 5.594734345490753 , 0.9217017380151371 ) ,
214
- ( 4.628808519201685 , 1.1805207831176578 ) ] ;
215
- let correct = Polygon :: new ( LineString ( correct_outside
216
- . iter ( )
217
- . map ( |e| Point :: new ( e. 0 , e. 1 ) )
218
- . collect :: < Vec < _ > > ( ) ) ,
219
- vec ! [ ] ) ;
236
+ let correct_outside = vec ! [
237
+ ( 4.628808519201685 , 1.1805207831176578 ) ,
238
+ ( 3.921701738015137 , 2.405265654509247 ) ,
239
+ ( 4.180520783117657 , 3.3711914807983154 ) ,
240
+ ( 5.405265654509247 , 4.0782982619848624 ) ,
241
+ ( 6.371191480798315 , 3.819479216882342 ) ,
242
+ ( 7.0782982619848624 , 2.594734345490753 ) ,
243
+ ( 6.819479216882343 , 1.6288085192016848 ) ,
244
+ ( 5.594734345490753 , 0.9217017380151371 ) ,
245
+ ( 4.628808519201685 , 1.1805207831176578 ) ,
246
+ ] ;
247
+ let correct = Polygon :: new (
248
+ LineString (
249
+ correct_outside
250
+ . iter ( )
251
+ . map ( |e| Point :: new ( e. 0 , e. 1 ) )
252
+ . collect :: < Vec < _ > > ( ) ,
253
+ ) ,
254
+ vec ! [ ] ,
255
+ ) ;
220
256
// results agree with Shapely / GEOS
221
257
assert_eq ! ( rotated, correct) ;
222
258
}
223
259
#[ test]
224
260
fn test_rotate_polygon_holes ( ) {
225
- let ls1 = LineString ( vec ! [ Point :: new( 5.0 , 1.0 ) ,
226
- Point :: new( 4.0 , 2.0 ) ,
227
- Point :: new( 4.0 , 3.0 ) ,
228
- Point :: new( 5.0 , 4.0 ) ,
229
- Point :: new( 6.0 , 4.0 ) ,
230
- Point :: new( 7.0 , 3.0 ) ,
231
- Point :: new( 7.0 , 2.0 ) ,
232
- Point :: new( 6.0 , 1.0 ) ,
233
- Point :: new( 5.0 , 1.0 ) ] ) ;
261
+ let ls1 = LineString ( vec ! [
262
+ Point :: new( 5.0 , 1.0 ) ,
263
+ Point :: new( 4.0 , 2.0 ) ,
264
+ Point :: new( 4.0 , 3.0 ) ,
265
+ Point :: new( 5.0 , 4.0 ) ,
266
+ Point :: new( 6.0 , 4.0 ) ,
267
+ Point :: new( 7.0 , 3.0 ) ,
268
+ Point :: new( 7.0 , 2.0 ) ,
269
+ Point :: new( 6.0 , 1.0 ) ,
270
+ Point :: new( 5.0 , 1.0 ) ,
271
+ ] ) ;
234
272
235
- let ls2 = LineString ( vec ! [ Point :: new( 5.0 , 1.3 ) ,
236
- Point :: new( 5.5 , 2.0 ) ,
237
- Point :: new( 6.0 , 1.3 ) ,
238
- Point :: new( 5.0 , 1.3 ) ] ) ;
273
+ let ls2 = LineString ( vec ! [
274
+ Point :: new( 5.0 , 1.3 ) ,
275
+ Point :: new( 5.5 , 2.0 ) ,
276
+ Point :: new( 6.0 , 1.3 ) ,
277
+ Point :: new( 5.0 , 1.3 ) ,
278
+ ] ) ;
239
279
240
- let ls3 = LineString ( vec ! [ Point :: new( 5. , 2.3 ) ,
241
- Point :: new( 5.5 , 3.0 ) ,
242
- Point :: new( 6. , 2.3 ) ,
243
- Point :: new( 5. , 2.3 ) ] ) ;
280
+ let ls3 = LineString ( vec ! [
281
+ Point :: new( 5. , 2.3 ) ,
282
+ Point :: new( 5.5 , 3.0 ) ,
283
+ Point :: new( 6. , 2.3 ) ,
284
+ Point :: new( 5. , 2.3 ) ,
285
+ ] ) ;
244
286
245
287
let poly1 = Polygon :: new ( ls1, vec ! [ ls2, ls3] ) ;
246
288
let rotated = poly1. rotate ( -15.0 ) ;
247
- let correct_outside = vec ! [ ( 4.628808519201685 , 1.180520783117658 ) ,
248
- ( 3.921701738015137 , 2.4052656545092472 ) ,
249
- ( 4.180520783117657 , 3.3711914807983154 ) ,
250
- ( 5.405265654509247 , 4.078298261984863 ) ,
251
- ( 6.371191480798315 , 3.8194792168823426 ) ,
252
- ( 7.0782982619848624 , 2.594734345490753 ) ,
253
- ( 6.819479216882343 , 1.628808519201685 ) ,
254
- ( 5.594734345490753 , 0.9217017380151373 ) ,
255
- ( 4.628808519201685 , 1.180520783117658 ) ]
256
- . iter ( )
257
- . map ( |e| Point :: new ( e. 0 , e. 1 ) )
258
- . collect :: < Vec < _ > > ( ) ;
259
- let correct_inside = vec ! [ ( 4.706454232732441 , 1.4702985310043786 ) ,
260
- ( 5.37059047744874 , 2.017037086855466 ) ,
261
- ( 5.672380059021509 , 1.2114794859018578 ) ,
262
- ( 4.706454232732441 , 1.4702985310043786 ) ]
263
- . iter ( )
264
- . map ( |e| Point :: new ( e. 0 , e. 1 ) )
265
- . collect :: < Vec < _ > > ( ) ;
289
+ let correct_outside = vec ! [
290
+ ( 4.628808519201685 , 1.180520783117658 ) ,
291
+ ( 3.921701738015137 , 2.4052656545092472 ) ,
292
+ ( 4.180520783117657 , 3.3711914807983154 ) ,
293
+ ( 5.405265654509247 , 4.078298261984863 ) ,
294
+ ( 6.371191480798315 , 3.8194792168823426 ) ,
295
+ ( 7.0782982619848624 , 2.594734345490753 ) ,
296
+ ( 6.819479216882343 , 1.628808519201685 ) ,
297
+ ( 5.594734345490753 , 0.9217017380151373 ) ,
298
+ ( 4.628808519201685 , 1.180520783117658 ) ,
299
+ ] . iter ( )
300
+ . map ( |e| Point :: new ( e. 0 , e. 1 ) )
301
+ . collect :: < Vec < _ > > ( ) ;
302
+ let correct_inside = vec ! [
303
+ ( 4.706454232732441 , 1.4702985310043786 ) ,
304
+ ( 5.37059047744874 , 2.017037086855466 ) ,
305
+ ( 5.672380059021509 , 1.2114794859018578 ) ,
306
+ ( 4.706454232732441 , 1.4702985310043786 ) ,
307
+ ] . iter ( )
308
+ . map ( |e| Point :: new ( e. 0 , e. 1 ) )
309
+ . collect :: < Vec < _ > > ( ) ;
266
310
// println!("INSIDE {:?}", rotated.interiors[0].0);
267
311
assert_eq ! ( rotated. exterior. 0 , correct_outside) ;
268
312
assert_eq ! ( rotated. interiors[ 0 ] . 0 , correct_inside) ;
@@ -282,7 +326,10 @@ mod test {
282
326
#[ test]
283
327
fn test_rotate_line_around_point ( ) {
284
328
let line0 = Line :: new ( Point :: new ( 0. , 0. ) , Point :: new ( 0. , 2. ) ) ;
285
- let line1 = Line :: new ( Point :: new ( 0. , 0. ) , Point :: new ( -2. , 0.00000000000000012246467991473532 ) ) ;
329
+ let line1 = Line :: new (
330
+ Point :: new ( 0. , 0. ) ,
331
+ Point :: new ( -2. , 0.00000000000000012246467991473532 ) ,
332
+ ) ;
286
333
assert_eq ! ( line0. rotate_around_point( 90. , & Point :: new( 0. , 0. ) ) , line1) ;
287
334
}
288
335
}
0 commit comments