codac4matlab 2.0.0.dev20__cp312-cp312-win32.whl → 2.0.0.dev25__cp312-cp312-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codac4matlab/_core.cp312-win32.pyd +0 -0
- codac4matlab/_graphics.cp312-win32.pyd +0 -0
- codac4matlab/_unsupported.cp312-win32.pyd +0 -0
- codac4matlab/core/__init__.py +39 -14
- codac4matlab/tests/test_AnalyticTraj.py +3 -4
- codac4matlab/tests/test_BoolInterval.py +57 -1
- codac4matlab/tests/test_ConvexPolygon.py +111 -18
- codac4matlab/tests/test_CtcCtcBoundary.py +1 -1
- codac4matlab/tests/test_CtcDeriv.py +434 -0
- codac4matlab/tests/test_CtcEval.py +214 -0
- codac4matlab/tests/test_CtcInverse.py +13 -4
- codac4matlab/tests/test_CtcPolygon.py +1 -1
- codac4matlab/tests/test_GaussJordan.py +34 -0
- codac4matlab/tests/test_IntFullPivLU.py +27 -0
- codac4matlab/tests/test_Interval.py +30 -6
- codac4matlab/tests/test_Interval_operations.py +6 -6
- codac4matlab/tests/test_OctaSym.py +9 -0
- codac4matlab/tests/test_Parallelepiped.py +35 -0
- codac4matlab/tests/test_Parallelepiped_eval.py +62 -0
- codac4matlab/tests/test_Polygon.py +14 -2
- codac4matlab/tests/test_SampledTraj.py +14 -1
- codac4matlab/tests/test_Segment.py +17 -2
- codac4matlab/tests/test_SepCtcBoundary.py +1 -1
- codac4matlab/tests/test_SepPolygon.py +1 -1
- codac4matlab/tests/test_SepTransform.py +5 -5
- codac4matlab/tests/test_Slice.py +78 -0
- codac4matlab/tests/test_Slice_polygon.py +208 -0
- codac4matlab/tests/test_SlicedTube.py +263 -5
- codac4matlab/tests/test_cart_prod.py +1 -0
- codac4matlab/tests/test_peibos.py +83 -0
- codac4matlab/tests/test_predefined_tubes.py +6 -6
- codac4matlab/tests/test_trunc.py +95 -0
- {codac4matlab-2.0.0.dev20.dist-info → codac4matlab-2.0.0.dev25.dist-info}/METADATA +1 -1
- {codac4matlab-2.0.0.dev20.dist-info → codac4matlab-2.0.0.dev25.dist-info}/RECORD +36 -27
- {codac4matlab-2.0.0.dev20.dist-info → codac4matlab-2.0.0.dev25.dist-info}/WHEEL +1 -1
- {codac4matlab-2.0.0.dev20.dist-info → codac4matlab-2.0.0.dev25.dist-info}/top_level.txt +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
codac4matlab/core/__init__.py
CHANGED
|
@@ -68,6 +68,9 @@ class AnalyticFunction:
|
|
|
68
68
|
|
|
69
69
|
def tube_eval(self,*args):
|
|
70
70
|
return self.f.tube_eval(*args)
|
|
71
|
+
|
|
72
|
+
def parallelepiped_eval(self,*args):
|
|
73
|
+
return self.f.parallelepiped_eval(*args)
|
|
71
74
|
|
|
72
75
|
def diff(self,*args):
|
|
73
76
|
return self.f.diff(*args)
|
|
@@ -115,10 +118,10 @@ class CtcInverse(Ctc_IntervalVector):
|
|
|
115
118
|
f_args = []
|
|
116
119
|
for a in f.args():
|
|
117
120
|
if a.size() == 1:
|
|
118
|
-
f_args.append(total_var
|
|
121
|
+
f_args.append(total_var.get_item_0(i))
|
|
119
122
|
i = i+1
|
|
120
123
|
else:
|
|
121
|
-
f_args.append(total_var.
|
|
124
|
+
f_args.append(total_var.subvector_0(i,i+a.size()-1))
|
|
122
125
|
i = i+a.size()
|
|
123
126
|
|
|
124
127
|
g = AnalyticFunction([total_var], f(*f_args))
|
|
@@ -153,9 +156,9 @@ class CtcInverse(Ctc_IntervalVector):
|
|
|
153
156
|
for xi in x:
|
|
154
157
|
k = xi.size()
|
|
155
158
|
if k==1:
|
|
156
|
-
xi &= total
|
|
159
|
+
xi &= total.get_item_0(i)
|
|
157
160
|
else:
|
|
158
|
-
xi &= total.
|
|
161
|
+
xi &= total.subvector_0(i,i+k-1)
|
|
159
162
|
i = i+k
|
|
160
163
|
return x
|
|
161
164
|
|
|
@@ -171,17 +174,17 @@ class CtcInverse(Ctc_IntervalVector):
|
|
|
171
174
|
for xi in x:
|
|
172
175
|
k = xi.size()
|
|
173
176
|
if k==1:
|
|
174
|
-
xi &= total
|
|
177
|
+
xi &= total.get_item_0(i)
|
|
175
178
|
else:
|
|
176
|
-
xi &= total.
|
|
179
|
+
xi &= total.subvector_0(i,i+k-1)
|
|
177
180
|
i = i+k
|
|
178
181
|
return x
|
|
179
182
|
|
|
180
183
|
def copy(self):
|
|
181
184
|
return self.c.copy()
|
|
182
185
|
|
|
183
|
-
def
|
|
184
|
-
return self.c.
|
|
186
|
+
def fnc(self):
|
|
187
|
+
return self.c.fnc()
|
|
185
188
|
|
|
186
189
|
|
|
187
190
|
class CtcInverseNotIn(Ctc_IntervalVector):
|
|
@@ -413,8 +416,8 @@ class AnalyticTraj:
|
|
|
413
416
|
def sampled(self, dt):
|
|
414
417
|
return self.traj.sampled(dt)
|
|
415
418
|
|
|
416
|
-
def primitive(self
|
|
417
|
-
return self.traj.primitive(
|
|
419
|
+
def primitive(self,*args):
|
|
420
|
+
return self.traj.primitive(*args)
|
|
418
421
|
|
|
419
422
|
def as_function(self):
|
|
420
423
|
return AnalyticFunction(self.traj.as_function())
|
|
@@ -479,6 +482,9 @@ class SlicedTube:
|
|
|
479
482
|
def last_slice(self):
|
|
480
483
|
return self.tube.last_slice()
|
|
481
484
|
|
|
485
|
+
def slice(self,*args):
|
|
486
|
+
return self.tube.slice(*args)
|
|
487
|
+
|
|
482
488
|
def is_empty(self):
|
|
483
489
|
return self.tube.is_empty()
|
|
484
490
|
|
|
@@ -488,8 +494,8 @@ class SlicedTube:
|
|
|
488
494
|
def codomain(self):
|
|
489
495
|
return self.tube.codomain()
|
|
490
496
|
|
|
491
|
-
def __call__(self
|
|
492
|
-
return self.tube.__call__(
|
|
497
|
+
def __call__(self,*args):
|
|
498
|
+
return self.tube.__call__(*args)
|
|
493
499
|
|
|
494
500
|
def enclosed_bounds(self,t):
|
|
495
501
|
return self.tube.enclosed_bounds(t)
|
|
@@ -532,6 +538,18 @@ class SlicedTube:
|
|
|
532
538
|
|
|
533
539
|
def primitive(self):
|
|
534
540
|
return self.tube.primitive()
|
|
541
|
+
|
|
542
|
+
def as_function(self):
|
|
543
|
+
return AnalyticFunction(self.tube.as_function())
|
|
544
|
+
|
|
545
|
+
def invert(self,*args):
|
|
546
|
+
return self.tube.invert(*args)
|
|
547
|
+
|
|
548
|
+
def all_reals_value(self):
|
|
549
|
+
return self.tube.all_reals_value()
|
|
550
|
+
|
|
551
|
+
def empty_value(self):
|
|
552
|
+
return self.tube.empty_value()
|
|
535
553
|
|
|
536
554
|
|
|
537
555
|
def fixpoint(contract, *x):
|
|
@@ -547,7 +565,7 @@ def fixpoint(contract, *x):
|
|
|
547
565
|
x = contract(x)
|
|
548
566
|
|
|
549
567
|
if not isinstance(x,tuple):
|
|
550
|
-
vol = x
|
|
568
|
+
vol = x.get_item_0(0).volume()
|
|
551
569
|
else:
|
|
552
570
|
vol = 0.0
|
|
553
571
|
for xi in x:
|
|
@@ -560,4 +578,11 @@ def fixpoint(contract, *x):
|
|
|
560
578
|
if w != oo:
|
|
561
579
|
vol += w
|
|
562
580
|
|
|
563
|
-
return x
|
|
581
|
+
return x
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
# Deprecated function draw_while_paving(..)
|
|
585
|
+
draw_while_paving = lambda *args, **kwargs: (_ for _ in ()).throw(
|
|
586
|
+
NotImplementedError("draw_while_paving(..) is deprecated,\n \
|
|
587
|
+
please replace by DefaultFigure.pave(..) (or any Figure2D object)")
|
|
588
|
+
)
|
|
@@ -13,7 +13,7 @@ import sys
|
|
|
13
13
|
import math
|
|
14
14
|
|
|
15
15
|
def prim_value(x):
|
|
16
|
-
return
|
|
16
|
+
return 0.+(1./3.)*math.pow(x,3)
|
|
17
17
|
|
|
18
18
|
class TestAnalyticTraj(unittest.TestCase):
|
|
19
19
|
|
|
@@ -48,11 +48,10 @@ class TestAnalyticTraj(unittest.TestCase):
|
|
|
48
48
|
self.assertTrue(Approx(sampled_traj(9.),1e-2) == 81.)
|
|
49
49
|
|
|
50
50
|
# Testing primitive computation from analytic trajectory
|
|
51
|
-
|
|
52
|
-
sampled_prim_traj = traj.primitive(x0,0.01)
|
|
51
|
+
sampled_prim_traj = traj.primitive(0.01)
|
|
53
52
|
self.assertTrue(sampled_prim_traj.tdomain() == Interval(-1,10))
|
|
54
53
|
self.assertTrue(Approx(sampled_prim_traj.codomain(),4e-1) == Interval(prim_value(0),prim_value(10.)))
|
|
55
|
-
self.assertTrue(sampled_prim_traj(-1.) ==
|
|
54
|
+
self.assertTrue(sampled_prim_traj(-1.) == 0)
|
|
56
55
|
self.assertTrue(Approx(sampled_prim_traj(0.),4e-1) == prim_value(0.))
|
|
57
56
|
self.assertTrue(Approx(sampled_prim_traj(2.),4e-1) == prim_value(2.))
|
|
58
57
|
self.assertTrue(Approx(sampled_prim_traj(5.),4e-1) == prim_value(5.))
|
|
@@ -13,28 +13,84 @@ from codac import *
|
|
|
13
13
|
class TestBoolInterval(unittest.TestCase):
|
|
14
14
|
|
|
15
15
|
def test_BoolInterval(self):
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
# Bitwise AND (&) — Intersection
|
|
17
18
|
self.assertTrue((BoolInterval.TRUE & BoolInterval.TRUE) == BoolInterval.TRUE)
|
|
18
19
|
self.assertTrue((BoolInterval.TRUE & BoolInterval.FALSE) == BoolInterval.EMPTY)
|
|
19
20
|
self.assertTrue((BoolInterval.TRUE & BoolInterval.UNKNOWN) == BoolInterval.TRUE)
|
|
20
21
|
self.assertTrue((BoolInterval.TRUE & BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
22
|
+
|
|
21
23
|
self.assertTrue((BoolInterval.FALSE & BoolInterval.FALSE) == BoolInterval.FALSE)
|
|
22
24
|
self.assertTrue((BoolInterval.FALSE & BoolInterval.UNKNOWN) == BoolInterval.FALSE)
|
|
23
25
|
self.assertTrue((BoolInterval.FALSE & BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
26
|
+
|
|
24
27
|
self.assertTrue((BoolInterval.EMPTY & BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
25
28
|
self.assertTrue((BoolInterval.EMPTY & BoolInterval.UNKNOWN) == BoolInterval.EMPTY)
|
|
29
|
+
|
|
26
30
|
self.assertTrue((BoolInterval.UNKNOWN & BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
27
31
|
|
|
32
|
+
# Bitwise OR (|) — Union
|
|
28
33
|
self.assertTrue((BoolInterval.TRUE | BoolInterval.TRUE) == BoolInterval.TRUE)
|
|
29
34
|
self.assertTrue((BoolInterval.TRUE | BoolInterval.FALSE) == BoolInterval.UNKNOWN)
|
|
30
35
|
self.assertTrue((BoolInterval.TRUE | BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
31
36
|
self.assertTrue((BoolInterval.TRUE | BoolInterval.EMPTY) == BoolInterval.TRUE)
|
|
37
|
+
|
|
32
38
|
self.assertTrue((BoolInterval.FALSE | BoolInterval.FALSE) == BoolInterval.FALSE)
|
|
33
39
|
self.assertTrue((BoolInterval.FALSE | BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
34
40
|
self.assertTrue((BoolInterval.FALSE | BoolInterval.EMPTY) == BoolInterval.FALSE)
|
|
41
|
+
|
|
35
42
|
self.assertTrue((BoolInterval.EMPTY | BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
36
43
|
self.assertTrue((BoolInterval.EMPTY | BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
44
|
+
|
|
37
45
|
self.assertTrue((BoolInterval.UNKNOWN | BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
38
46
|
|
|
47
|
+
# Logical AND (&&)
|
|
48
|
+
self.assertTrue(logical_and(BoolInterval.TRUE, BoolInterval.TRUE) == BoolInterval.TRUE)
|
|
49
|
+
self.assertTrue(logical_and(BoolInterval.TRUE, BoolInterval.FALSE) == BoolInterval.FALSE)
|
|
50
|
+
self.assertTrue(logical_and(BoolInterval.TRUE, BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
51
|
+
self.assertTrue(logical_and(BoolInterval.TRUE, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
52
|
+
|
|
53
|
+
self.assertTrue(logical_and(BoolInterval.FALSE, BoolInterval.TRUE) == BoolInterval.FALSE)
|
|
54
|
+
self.assertTrue(logical_and(BoolInterval.FALSE, BoolInterval.FALSE) == BoolInterval.FALSE)
|
|
55
|
+
self.assertTrue(logical_and(BoolInterval.FALSE, BoolInterval.UNKNOWN) == BoolInterval.FALSE)
|
|
56
|
+
self.assertTrue(logical_and(BoolInterval.FALSE, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
57
|
+
|
|
58
|
+
self.assertTrue(logical_and(BoolInterval.UNKNOWN, BoolInterval.TRUE) == BoolInterval.UNKNOWN)
|
|
59
|
+
self.assertTrue(logical_and(BoolInterval.UNKNOWN, BoolInterval.FALSE) == BoolInterval.FALSE)
|
|
60
|
+
self.assertTrue(logical_and(BoolInterval.UNKNOWN, BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
61
|
+
self.assertTrue(logical_and(BoolInterval.UNKNOWN, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
62
|
+
|
|
63
|
+
self.assertTrue(logical_and(BoolInterval.EMPTY, BoolInterval.TRUE) == BoolInterval.EMPTY)
|
|
64
|
+
self.assertTrue(logical_and(BoolInterval.EMPTY, BoolInterval.FALSE) == BoolInterval.EMPTY)
|
|
65
|
+
self.assertTrue(logical_and(BoolInterval.EMPTY, BoolInterval.UNKNOWN) == BoolInterval.EMPTY)
|
|
66
|
+
self.assertTrue(logical_and(BoolInterval.EMPTY, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
67
|
+
|
|
68
|
+
# Logical OR (||)
|
|
69
|
+
self.assertTrue(logical_or(BoolInterval.TRUE, BoolInterval.TRUE) == BoolInterval.TRUE)
|
|
70
|
+
self.assertTrue(logical_or(BoolInterval.TRUE, BoolInterval.FALSE) == BoolInterval.TRUE)
|
|
71
|
+
self.assertTrue(logical_or(BoolInterval.TRUE, BoolInterval.UNKNOWN) == BoolInterval.TRUE)
|
|
72
|
+
self.assertTrue(logical_or(BoolInterval.TRUE, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
73
|
+
|
|
74
|
+
self.assertTrue(logical_or(BoolInterval.FALSE, BoolInterval.TRUE) == BoolInterval.TRUE)
|
|
75
|
+
self.assertTrue(logical_or(BoolInterval.FALSE, BoolInterval.FALSE) == BoolInterval.FALSE)
|
|
76
|
+
self.assertTrue(logical_or(BoolInterval.FALSE, BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
77
|
+
self.assertTrue(logical_or(BoolInterval.FALSE, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
78
|
+
|
|
79
|
+
self.assertTrue(logical_or(BoolInterval.UNKNOWN, BoolInterval.TRUE) == BoolInterval.TRUE)
|
|
80
|
+
self.assertTrue(logical_or(BoolInterval.UNKNOWN, BoolInterval.FALSE) == BoolInterval.UNKNOWN)
|
|
81
|
+
self.assertTrue(logical_or(BoolInterval.UNKNOWN, BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
82
|
+
self.assertTrue(logical_or(BoolInterval.UNKNOWN, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
83
|
+
|
|
84
|
+
self.assertTrue(logical_or(BoolInterval.EMPTY, BoolInterval.TRUE) == BoolInterval.EMPTY)
|
|
85
|
+
self.assertTrue(logical_or(BoolInterval.EMPTY, BoolInterval.FALSE) == BoolInterval.EMPTY)
|
|
86
|
+
self.assertTrue(logical_or(BoolInterval.EMPTY, BoolInterval.UNKNOWN) == BoolInterval.EMPTY)
|
|
87
|
+
self.assertTrue(logical_or(BoolInterval.EMPTY, BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
88
|
+
|
|
89
|
+
# Complement (~)
|
|
90
|
+
self.assertTrue((~BoolInterval.TRUE) == BoolInterval.FALSE)
|
|
91
|
+
self.assertTrue((~BoolInterval.FALSE) == BoolInterval.TRUE)
|
|
92
|
+
self.assertTrue((~BoolInterval.UNKNOWN) == BoolInterval.UNKNOWN)
|
|
93
|
+
self.assertTrue((~BoolInterval.EMPTY) == BoolInterval.EMPTY)
|
|
94
|
+
|
|
39
95
|
if __name__ == '__main__':
|
|
40
96
|
unittest.main()
|
|
@@ -15,32 +15,32 @@ class TestConvexPolygon(unittest.TestCase):
|
|
|
15
15
|
def test_ConvexPolygon_degenerate_base(self):
|
|
16
16
|
|
|
17
17
|
p = ConvexPolygon([[1,2],[1,2]])
|
|
18
|
-
self.assertTrue(len(p.
|
|
18
|
+
self.assertTrue(len(p.vertices()) == 1)
|
|
19
19
|
|
|
20
20
|
p = ConvexPolygon([[1,3],[1,2],[1,2]])
|
|
21
|
-
self.assertTrue(len(p.
|
|
21
|
+
self.assertTrue(len(p.vertices()) == 2)
|
|
22
22
|
|
|
23
23
|
p = ConvexPolygon([[1,2],[1,3],[1,2],[1,2]])
|
|
24
|
-
self.assertTrue(len(p.
|
|
24
|
+
self.assertTrue(len(p.vertices()) == 2)
|
|
25
25
|
|
|
26
26
|
p = ConvexPolygon([[1,2],[1,3],[1,3],[1,2],[1,2]])
|
|
27
|
-
self.assertTrue(len(p.
|
|
27
|
+
self.assertTrue(len(p.vertices()) == 2)
|
|
28
28
|
|
|
29
29
|
self.assertTrue(len(convex_hull([[1,2],[1,2],[1,2]])) == 1)
|
|
30
30
|
p = ConvexPolygon([[1,2],[1,2],[1,2]])
|
|
31
|
-
self.assertTrue(len(p.
|
|
31
|
+
self.assertTrue(len(p.vertices()) == 1)
|
|
32
32
|
|
|
33
33
|
p = ConvexPolygon([[1,2],[1,3]])
|
|
34
|
-
self.assertTrue(len(p.
|
|
34
|
+
self.assertTrue(len(p.vertices()) == 2)
|
|
35
35
|
|
|
36
36
|
p = ConvexPolygon([[1,2],[1,3],[1,2]])
|
|
37
|
-
self.assertTrue(len(p.
|
|
37
|
+
self.assertTrue(len(p.vertices()) == 2)
|
|
38
38
|
|
|
39
39
|
p = ConvexPolygon([[1,2],[1,3],[1,2],[1,2]])
|
|
40
|
-
self.assertTrue(len(p.
|
|
40
|
+
self.assertTrue(len(p.vertices()) == 2)
|
|
41
41
|
|
|
42
42
|
p = ConvexPolygon([[1,2],[1,3],[1,3],[1,2]])
|
|
43
|
-
self.assertTrue(len(p.
|
|
43
|
+
self.assertTrue(len(p.vertices()) == 2)
|
|
44
44
|
|
|
45
45
|
def test_ConvexPolygon_degenerate_cases(self):
|
|
46
46
|
|
|
@@ -97,6 +97,8 @@ class TestConvexPolygon(unittest.TestCase):
|
|
|
97
97
|
# Degenerate case
|
|
98
98
|
p1 = ConvexPolygon([[4000,200]])
|
|
99
99
|
p2 = ConvexPolygon(IntervalVector([4000,200]))
|
|
100
|
+
self.assertTrue(p1.box() == IntervalVector([4000,200]))
|
|
101
|
+
self.assertTrue(p2.box() == IntervalVector([4000,200]))
|
|
100
102
|
self.assertTrue((p1 & p2) == p1) # same polygon
|
|
101
103
|
|
|
102
104
|
p1 = ConvexPolygon([[1,1],[2,4],[7,5],[6,2]])
|
|
@@ -104,14 +106,14 @@ class TestConvexPolygon(unittest.TestCase):
|
|
|
104
106
|
q = p1 & p2
|
|
105
107
|
self.assertTrue(Approx(q) == Polygon([[2,1.2],[6,2],[6,4.8],[2,4]]))
|
|
106
108
|
self.assertTrue(len(q.edges()) == 4)
|
|
107
|
-
self.assertTrue(len(q.
|
|
109
|
+
self.assertTrue(len(q.vertices()) == 4)
|
|
108
110
|
|
|
109
111
|
p1 = ConvexPolygon([[1,1],[2,4],[7,5],[6,2]])
|
|
110
112
|
p2 = ConvexPolygon(IntervalVector([[3,5],[1,5]]))
|
|
111
113
|
q = p1 & p2
|
|
112
114
|
self.assertTrue(Approx(q) == Polygon([[3,1.4],[5,1.8],[5,4.6],[3,4.2]]))
|
|
113
115
|
self.assertTrue(len(q.edges()) == 4)
|
|
114
|
-
self.assertTrue(len(q.
|
|
116
|
+
self.assertTrue(len(q.vertices()) == 4)
|
|
115
117
|
|
|
116
118
|
# Degenerated box
|
|
117
119
|
p1 = ConvexPolygon([[1,1],[2,4],[7,5],[6,2]])
|
|
@@ -133,35 +135,35 @@ class TestConvexPolygon(unittest.TestCase):
|
|
|
133
135
|
|
|
134
136
|
q = p1 & p2
|
|
135
137
|
self.assertTrue(Approx(q) == Polygon([[4,4.4],[4,1.6]]))
|
|
136
|
-
self.assertTrue(len(q.
|
|
138
|
+
self.assertTrue(len(q.vertices()) == 2)
|
|
137
139
|
|
|
138
140
|
# Degenerated polygon
|
|
139
141
|
p1 = ConvexPolygon([[1,1],[2,4],[7,5],[6,2]])
|
|
140
142
|
p2 = ConvexPolygon([[4,1],[4,5]])
|
|
141
143
|
q = p1 & p2
|
|
142
144
|
self.assertTrue(Approx(q) == Polygon([[4,4.4],[4,1.6]]))
|
|
143
|
-
self.assertTrue(len(q.
|
|
145
|
+
self.assertTrue(len(q.vertices()) == 2)
|
|
144
146
|
|
|
145
147
|
# Point intersection
|
|
146
148
|
p1 = ConvexPolygon([[1,1],[2,4],[7,5],[6,2]])
|
|
147
149
|
p2 = ConvexPolygon([[2,4],[-4,4],[0,8]])
|
|
148
150
|
q = p1 & p2
|
|
149
151
|
self.assertTrue(q == Polygon([[2,4]]))
|
|
150
|
-
self.assertTrue(len(q.
|
|
152
|
+
self.assertTrue(len(q.vertices()) == 1)
|
|
151
153
|
|
|
152
154
|
# Point intersection, line polygon
|
|
153
155
|
p1 = ConvexPolygon([[1,1],[2,4],[7,5],[6,2]])
|
|
154
156
|
p2 = ConvexPolygon([[2,4],[-4,4]])
|
|
155
157
|
q = p1 & p2
|
|
156
158
|
self.assertTrue(q == Polygon([[2,4]]))
|
|
157
|
-
self.assertTrue(len(q.
|
|
159
|
+
self.assertTrue(len(q.vertices()) == 1)
|
|
158
160
|
|
|
159
161
|
# Empty intersection
|
|
160
162
|
p1 = ConvexPolygon([[1,1],[2,4],[7,5],[6,2]])
|
|
161
163
|
p2 = ConvexPolygon([[5,1.5],[8,2],[8,0],[5,0]])
|
|
162
164
|
q = p1 & p2
|
|
163
165
|
self.assertTrue(q == Polygon.empty())
|
|
164
|
-
self.assertTrue(len(q.
|
|
166
|
+
self.assertTrue(len(q.vertices()) == 0)
|
|
165
167
|
self.assertTrue(q.is_empty())
|
|
166
168
|
|
|
167
169
|
# Empty intersection, degenerate case
|
|
@@ -169,7 +171,7 @@ class TestConvexPolygon(unittest.TestCase):
|
|
|
169
171
|
p2 = ConvexPolygon([[5,1.5],[80,2]])
|
|
170
172
|
q = p1 & p2
|
|
171
173
|
self.assertTrue(q == Polygon.empty())
|
|
172
|
-
self.assertTrue(len(q.
|
|
174
|
+
self.assertTrue(len(q.vertices()) == 0)
|
|
173
175
|
self.assertTrue(q.is_empty())
|
|
174
176
|
|
|
175
177
|
# Intersection of empty polygons
|
|
@@ -196,12 +198,103 @@ class TestConvexPolygon(unittest.TestCase):
|
|
|
196
198
|
# Other test with inflated points
|
|
197
199
|
p1 = ConvexPolygon(IntervalVector([[-4,4],[-3,3]]))
|
|
198
200
|
a1,a2 = IntervalVector([-4,-6]), IntervalVector([-4,6])
|
|
199
|
-
a1.inflate(1e-10)
|
|
201
|
+
a1.inflate(1e-10)
|
|
202
|
+
a2.inflate(1e-10)
|
|
200
203
|
p2 = ConvexPolygon([Segment(a1,a2)])
|
|
201
204
|
q = p1 & p2
|
|
202
205
|
self.assertTrue(len(q.edges()) == 1)
|
|
203
206
|
self.assertTrue(Approx(q.edges()[0][0],1e-5) == IntervalVector([-4,-3]))
|
|
204
207
|
self.assertTrue(Approx(q.edges()[0][1],1e-5) == IntervalVector([-4,3]))
|
|
205
208
|
|
|
209
|
+
# Parallel edges
|
|
210
|
+
p1 = ConvexPolygon([
|
|
211
|
+
[-1,-10],
|
|
212
|
+
[3,-10],
|
|
213
|
+
[3,1],
|
|
214
|
+
[-1,6],
|
|
215
|
+
])
|
|
216
|
+
p2 = ConvexPolygon([
|
|
217
|
+
[-1,10],
|
|
218
|
+
[-1,-1],
|
|
219
|
+
[3,-6],
|
|
220
|
+
[3,10],
|
|
221
|
+
])
|
|
222
|
+
q = p1 & p2
|
|
223
|
+
self.assertTrue(q == ConvexPolygon([
|
|
224
|
+
[3,-6],
|
|
225
|
+
[3,1],
|
|
226
|
+
[-1,6],
|
|
227
|
+
[-1,-1],
|
|
228
|
+
]))
|
|
229
|
+
|
|
230
|
+
# Parallel edges towards infinity
|
|
231
|
+
p1 = ConvexPolygon([
|
|
232
|
+
[-1,next_float(-oo)],
|
|
233
|
+
[3,next_float(-oo)],
|
|
234
|
+
[3,1],
|
|
235
|
+
[-1,6],
|
|
236
|
+
])
|
|
237
|
+
p2 = ConvexPolygon([
|
|
238
|
+
[-1,prev_float(oo)],
|
|
239
|
+
[-1,-1],
|
|
240
|
+
[3,-6],
|
|
241
|
+
[3,prev_float(oo)],
|
|
242
|
+
])
|
|
243
|
+
q = p1 & p2
|
|
244
|
+
self.assertTrue(q == ConvexPolygon([
|
|
245
|
+
[3,-6],
|
|
246
|
+
[3,1],
|
|
247
|
+
[-1,6],
|
|
248
|
+
[-1,-1],
|
|
249
|
+
]))
|
|
250
|
+
|
|
251
|
+
p1 = ConvexPolygon([[4,3.5],[5,4],[4,4.5]])
|
|
252
|
+
p2 = ConvexPolygon([[4,3.5],[5,3.5],[5,4.25],[4.5,4.25],[4,4]])
|
|
253
|
+
self.assertTrue(Approx(p1 & p2) == ConvexPolygon([[4,4],[4,3.5],[5,4],[4.5,4.25]]))
|
|
254
|
+
|
|
255
|
+
p1 = ConvexPolygon([[4,4],[4,3.5],[5,4],[4.5,4.25]])
|
|
256
|
+
p2 = ConvexPolygon(IntervalVector([[4,5],[4.1]]))
|
|
257
|
+
self.assertTrue(Approx(p1 & p2, 1e-10) == ConvexPolygon(IntervalVector([[4.2,4.8],[4.1]])))
|
|
258
|
+
|
|
259
|
+
p1 = ConvexPolygon([[4,4],[4,3.5],[5,4],[4.5,4.25]])
|
|
260
|
+
p2 = ConvexPolygon(IntervalVector([[4,5],Interval(41)/10]))
|
|
261
|
+
self.assertTrue(Approx(p1 & p2, 1e-10) == ConvexPolygon(IntervalVector([[4.2,4.8],Interval(41)/10])))
|
|
262
|
+
|
|
263
|
+
p1 = ConvexPolygon([
|
|
264
|
+
IntervalVector([[0.0999999, 0.100001],[0.989016, 0.989017]]),
|
|
265
|
+
IntervalVector([[0.0999999, 0.100001],[1.0015, 1.00151]]),
|
|
266
|
+
IntervalVector([[0, 0],[0.999999, 1]]),
|
|
267
|
+
IntervalVector([[0, 0],[1, 1.00001]])
|
|
268
|
+
])
|
|
269
|
+
|
|
270
|
+
p2 = ConvexPolygon([
|
|
271
|
+
IntervalVector([[0, 0],[0.987514, 0.987515]]),
|
|
272
|
+
IntervalVector([[0.1, 0.100001],[0.989016, 0.989017]]),
|
|
273
|
+
IntervalVector([[0.1, 0.100001],[1.0015, 1.00151]]),
|
|
274
|
+
IntervalVector([[0, 0],[1.01248, 1.01249]]),
|
|
275
|
+
])
|
|
276
|
+
|
|
277
|
+
self.assertTrue(Approx(p1 & p2, 1e-5) == ConvexPolygon([
|
|
278
|
+
[[0.0997289, 0.100002],[0.989016, 0.989938]],
|
|
279
|
+
[[0.0995829, 0.100002],[1.00059, 1.00151]],
|
|
280
|
+
[[0, 0],[0.999547, 1.00047]]
|
|
281
|
+
]))
|
|
282
|
+
|
|
283
|
+
p1 &= p2
|
|
284
|
+
|
|
285
|
+
m = IntervalVector([6.5,1])
|
|
286
|
+
p1 = ConvexPolygon(m)
|
|
287
|
+
p2 = ConvexPolygon([
|
|
288
|
+
[[6.49999, 6.50001],[0.759358, 0.759359]],
|
|
289
|
+
[[6.49999, 6.50001],[1.19382, 1.19383]],
|
|
290
|
+
[[6.4, 6.40001],[1.20537, 1.20538]],
|
|
291
|
+
[[6.4, 6.40001],[0.78097, 0.780971]],
|
|
292
|
+
])
|
|
293
|
+
|
|
294
|
+
s = Segment(IntervalVector([[6.49999, 6.50001],[0.759358, 0.759359]]), IntervalVector([[6.49999, 6.50001],[1.19382, 1.19383]]))
|
|
295
|
+
self.assertTrue(s.contains(m) == BoolInterval.UNKNOWN)
|
|
296
|
+
self.assertTrue((p1 & p2) == ConvexPolygon([m]))
|
|
297
|
+
|
|
298
|
+
|
|
206
299
|
if __name__ == '__main__':
|
|
207
300
|
unittest.main()
|
|
@@ -26,7 +26,7 @@ class TestCtcCtcBoundary(unittest.TestCase):
|
|
|
26
26
|
| CtcSegment([[1],[0]], [[0],[1]]) | CtcSegment([[0],[1]], [[-1],[0]])
|
|
27
27
|
|
|
28
28
|
ctc_diamond = CtcCtcBoundary(ctc_bound_diamond,test_inside_diamond)
|
|
29
|
-
#
|
|
29
|
+
#DefaultFigure.pave(IntervalVector([[-2,2],[-2,2]]), ctc_diamond, 0.1)
|
|
30
30
|
|
|
31
31
|
x = IntervalVector(2)
|
|
32
32
|
ctc_diamond.contract(x)
|