@@ -1260,6 +1260,45 @@ def test_arith_vect(self):
1260
1260
array_compare (a [1 ], ry - 1 )
1261
1261
array_compare (a [2 ], rz - 1 )
1262
1262
1263
+ def test_angle (self ):
1264
+ # angle between SO3's
1265
+ r1 = SO3 .Rx (0.1 )
1266
+ r2 = SO3 .Rx (0.2 )
1267
+ for metric in range (6 ):
1268
+ self .assertAlmostEqual (r1 .angdist (other = r1 , metric = metric ), 0.0 )
1269
+ self .assertGreater (r1 .angdist (other = r2 , metric = metric ), 0.0 )
1270
+ self .assertAlmostEqual (
1271
+ r1 .angdist (other = r2 , metric = metric ), r2 .angdist (other = r1 , metric = metric )
1272
+ )
1273
+ # angle between SE3's
1274
+ p1a , p1b = SE3 .Rx (0.1 ), SE3 .Rx (0.1 , t = (1 , 2 , 3 ))
1275
+ p2a , p2b = SE3 .Rx (0.2 ), SE3 .Rx (0.2 , t = (3 , 2 , 1 ))
1276
+ for metric in range (6 ):
1277
+ self .assertAlmostEqual (p1a .angdist (other = p1a , metric = metric ), 0.0 )
1278
+ self .assertGreater (p1a .angdist (other = p2a , metric = metric ), 0.0 )
1279
+ self .assertAlmostEqual (p1a .angdist (other = p1b , metric = metric ), 0.0 )
1280
+ self .assertAlmostEqual (
1281
+ p1a .angdist (other = p2a , metric = metric ),
1282
+ p2a .angdist (other = p1a , metric = metric ),
1283
+ )
1284
+ self .assertAlmostEqual (
1285
+ p1a .angdist (other = p2a , metric = metric ),
1286
+ p1a .angdist (other = p2b , metric = metric ),
1287
+ )
1288
+ # angdist is not implemented for mismatched types
1289
+ with self .assertRaises (ValueError ):
1290
+ _ = r1 .angdist (p1a )
1291
+
1292
+ with self .assertRaises (ValueError ):
1293
+ _ = r1 ._op2 (right = p1a , op = r1 .angdist )
1294
+
1295
+ with self .assertRaises (ValueError ):
1296
+ _ = p1a ._op2 (right = r1 , op = p1a .angdist )
1297
+
1298
+ # in general, the _op2 interface enforces an isinstance check.
1299
+ with self .assertRaises (TypeError ):
1300
+ _ = r1 ._op2 (right = (1 , 0 , 0 ), op = r1 .angdist )
1301
+
1263
1302
def test_functions (self ):
1264
1303
# inv
1265
1304
# .T
0 commit comments