re-organised test suite
This commit is contained in:
parent
f60475eb3d
commit
dc5b1c708b
|
@ -190,10 +190,6 @@ class GeometricProblem (Notifier, Listener):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_rigid(self, vars):
|
|
||||||
print "GeometricProblem.get_rigid NOT IMPLEMENTED"
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_fix(self, p):
|
def get_fix(self, p):
|
||||||
"""return the fix constraint on given point, or None"""
|
"""return the fix constraint on given point, or None"""
|
||||||
on_p = self.cg.get_constraints_on(p)
|
on_p = self.cg.get_constraints_on(p)
|
||||||
|
@ -209,6 +205,15 @@ class GeometricProblem (Notifier, Listener):
|
||||||
print "GeometricProblem.get_coincidence NOT IMPLEMENTED"
|
print "GeometricProblem.get_coincidence NOT IMPLEMENTED"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_rigid(self, vars):
|
||||||
|
print "GeometricProblem.get_rigid NOT IMPLEMENTED"
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_mate(self, vars):
|
||||||
|
print "GeometricProblem.get_mate NOT IMPLEMENTED"
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def verify(self, solution):
|
def verify(self, solution):
|
||||||
"""returns true iff all constraints satisfied by given solution.
|
"""returns true iff all constraints satisfied by given solution.
|
||||||
solution is a dictionary mapping variables (names) to values (points)"""
|
solution is a dictionary mapping variables (names) to values (points)"""
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# ----------- random problem generation ----------------
|
#----------- random problem generation ----------------
|
||||||
|
|
||||||
import random
|
import random
|
||||||
from diagnostic import diag_print
|
from diagnostic import diag_print
|
||||||
|
@ -328,12 +328,11 @@ def random_triangular_problem_3D(npoints, radius, roundoff, pangle):
|
||||||
problem.add_constraint(AngleConstraint(pl,p,pr,angle))
|
problem.add_constraint(AngleConstraint(pl,p,pr,angle))
|
||||||
return problem
|
return problem
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
#problem = random_triangular_problem_3D(10, 10.0, 0.0, 0.5)
|
#problem = random_triangular_problem_3D(10, 10.0, 0.0, 0.5)
|
||||||
problem = random_problem_2D(10, 10.0, 0.0, 0.6)
|
problem = random_problem_2D(10, 10.0, 0.0, 0.6)
|
||||||
problem = randomize_angles(problem)
|
problem = randomize_angles(problem)
|
||||||
print problem
|
print problem
|
||||||
|
|
||||||
if __name__ == "__main__": test()
|
if __name__ == "__main__":
|
||||||
|
test()
|
||||||
|
|
985
test/test.py
985
test/test.py
|
@ -1,985 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
"""This module provides some tests for the GeoSolver.
|
|
||||||
The tests are also simple examples of how to use of the GeomSolver API"""
|
|
||||||
|
|
||||||
from geosolver.geometric import *
|
|
||||||
from geosolver.vector import vector
|
|
||||||
from geosolver.randomproblem import *
|
|
||||||
from geosolver.diagnostic import diag_select, diag_print
|
|
||||||
import geosolver.tolerance as tolerance
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
# ---------- 3D problems -----
|
|
||||||
|
|
||||||
def fix3_problem_3d():
|
|
||||||
"""A problem with a fix constraint"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.0, 0.0, 1.0]))
|
|
||||||
#problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
#problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
#problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(FixConstraint('v1', vector([0.0,0.0,0.0])))
|
|
||||||
problem.add_constraint(FixConstraint('v2', vector([10.0,0.0,0.0])))
|
|
||||||
problem.add_constraint(FixConstraint('v3', vector([5.0,5.0,0.0])))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def fix2_problem_3d():
|
|
||||||
"""A problem with a fix constraint"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.0, 0.0, 1.0]))
|
|
||||||
#problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(FixConstraint('v1', vector([0.0,0.0,0.0])))
|
|
||||||
problem.add_constraint(FixConstraint('v2', vector([10.0,0.0,0.0])))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def fix1_problem_3d():
|
|
||||||
"""A problem with a fix constraint"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.0, 0.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(FixConstraint('v1', vector([0.0,0.0,0.0])))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def double_banana_problem():
|
|
||||||
"""The double banana problem"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
|
||||||
|
|
||||||
problem.add_point('w1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('w2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('w3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'w2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'w3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w2', 'w3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w3', 'v5', 10.0))
|
|
||||||
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def double_banana_plus_one_problem():
|
|
||||||
"""The double banana problem, plus one constraint (well-constrained)"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
|
||||||
|
|
||||||
problem.add_point('w1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('w2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('w3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'w2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'w3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w2', 'w3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('w3', 'v5', 10.0))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'w1', 10.0))
|
|
||||||
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
def double_tetrahedron_problem():
|
|
||||||
"""The double tetrahedron problem"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
def dad_tetrahedron_problem():
|
|
||||||
"""The double tetrahedron problem with an angle"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(AngleConstraint('v2', 'v1','v3', 60.0*math.pi/180.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def ada_tetrahedron_problem():
|
|
||||||
"""The double tetrahedron problem with an angle"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(AngleConstraint('v3', 'v1','v2', 60.0*math.pi/180.0))
|
|
||||||
problem.add_constraint(AngleConstraint('v1', 'v2','v3', 60.0*math.pi/180.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def ada_3d_problem():
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
|
||||||
problem.add_constraint(AngleConstraint('v3', 'v1', 'v2',
|
|
||||||
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('v1', 'v2', 'v3',
|
|
||||||
angle_3p(problem.get_point('v1'), problem.get_point('v2'), problem.get_point('v3'))
|
|
||||||
))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def overconstrained_tetra():
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
# overconstrain me!
|
|
||||||
problem.add_constraint(AngleConstraint('v1', 'v2', 'v3', math.pi/3))
|
|
||||||
#problem.add_constraint(AngleConstraint('v1', 'v2', 'v3', math.pi/4))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def diamond_3d():
|
|
||||||
"""creates a diamond shape with point 'v1'...'v4' in 3D with one solution"""
|
|
||||||
# Following should be well-constraint, gives underconstrained (need extra rule/pattern)
|
|
||||||
L=10.0
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([-5.0, 5.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([5.0, 5.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.0, 10.0, 0.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', L))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', L))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', L))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', L))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', L))
|
|
||||||
# this bit of code constrains the points v1...v4 in a plane with point p above it
|
|
||||||
problem.add_point('p', vector([0.0, 0.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'p', 1.0))
|
|
||||||
problem.add_constraint(AngleConstraint('v2','v1','p', math.pi/2))
|
|
||||||
problem.add_constraint(AngleConstraint('v3','v1','p', math.pi/2))
|
|
||||||
problem.add_constraint(AngleConstraint('v4','v1','p', math.pi/2))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
# -------- 2D problems
|
|
||||||
|
|
||||||
def ddd_problem():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v3',distance_2p(problem.get_point('v1'), problem.get_point('v3'))))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2','v3',distance_2p(problem.get_point('v2'), problem.get_point('v3'))))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def dad_problem():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v2',
|
|
||||||
distance_2p(problem.get_point('v1'), problem.get_point('v2'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2','v3',
|
|
||||||
distance_2p(problem.get_point('v2'), problem.get_point('v3'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('v1','v2','v3',
|
|
||||||
angle_3p(problem.get_point('v1'), problem.get_point('v2'), problem.get_point('v3'))
|
|
||||||
))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def add_problem():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v2',
|
|
||||||
distance_2p(problem.get_point('v1'), problem.get_point('v2'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2','v3',
|
|
||||||
distance_2p(problem.get_point('v2'), problem.get_point('v3'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('v3','v1','v2',
|
|
||||||
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
|
||||||
))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
def aad_problem():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
|
||||||
problem.add_constraint(AngleConstraint('v2', 'v3', 'v1',
|
|
||||||
angle_3p(problem.get_point('v2'), problem.get_point('v3'), problem.get_point('v1'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('v3', 'v1', 'v2',
|
|
||||||
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
|
||||||
))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def ada_problem():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
|
||||||
problem.add_constraint(AngleConstraint('v3', 'v1', 'v2',
|
|
||||||
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('v1', 'v2', 'v3',
|
|
||||||
angle_3p(problem.get_point('v1'), problem.get_point('v2'), problem.get_point('v3'))
|
|
||||||
))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def propagation_problem():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v4', vector([random.random() for i in [1,2]]))
|
|
||||||
problem.add_point('v5', vector([random.random() for i in [1,2]]))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v2',
|
|
||||||
distance_2p(problem.get_point('v1'), problem.get_point('v2'))
|
|
||||||
))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v3',
|
|
||||||
distance_2p(problem.get_point('v1'), problem.get_point('v3'))
|
|
||||||
))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v2','v3',
|
|
||||||
distance_2p(problem.get_point('v2'), problem.get_point('v3'))
|
|
||||||
))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v2','v4',
|
|
||||||
distance_2p(problem.get_point('v2'), problem.get_point('v4'))
|
|
||||||
))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v1','v5',
|
|
||||||
distance_2p(problem.get_point('v1'), problem.get_point('v5'))
|
|
||||||
))
|
|
||||||
|
|
||||||
problem.add_constraint(AngleConstraint('v3', 'v1', 'v4',
|
|
||||||
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v4'))
|
|
||||||
))
|
|
||||||
|
|
||||||
problem.add_constraint(AngleConstraint('v3', 'v2', 'v5',
|
|
||||||
angle_3p(problem.get_point('v3'), problem.get_point('v2'), problem.get_point('v5'))
|
|
||||||
))
|
|
||||||
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
def balloon_problem():
|
|
||||||
"""test angle propagation via balloon"""
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('A', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('B', vector([1.0, -1.0]))
|
|
||||||
problem.add_point('C', vector([1.0, +1.0]))
|
|
||||||
problem.add_point('D', vector([2.0, 0.0]))
|
|
||||||
problem.add_constraint(AngleConstraint('B','A','C',
|
|
||||||
angle_3p(problem.get_point('B'), problem.get_point('A'), problem.get_point('C'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('A','B','C',
|
|
||||||
angle_3p(problem.get_point('A'), problem.get_point('B'), problem.get_point('C'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('B','C','D',
|
|
||||||
angle_3p(problem.get_point('B'), problem.get_point('C'), problem.get_point('D'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(AngleConstraint('C','D','B',
|
|
||||||
angle_3p(problem.get_point('C'), problem.get_point('D'), problem.get_point('B'))
|
|
||||||
))
|
|
||||||
problem.add_constraint(DistanceConstraint('A', 'D', 6.0))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def double_triangle():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0]))
|
|
||||||
problem.add_point('v4', vector([1.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def triple_double_triangle():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('QX', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('QA2', vector([1.0, 0.0]))
|
|
||||||
problem.add_point('QA3', vector([0.0, 1.0]))
|
|
||||||
problem.add_point('QY', vector([1.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('QX', 'QA2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QX', 'QA3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QA2', 'QA3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QA2', 'QY', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QA3', 'QY', 10.0))
|
|
||||||
|
|
||||||
#problem.add_point('QX', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('QB2', vector([1.0, 0.0]))
|
|
||||||
problem.add_point('QZ', vector([0.0, 1.0]))
|
|
||||||
problem.add_point('QB4', vector([1.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('QX', 'QB2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QX', 'QZ', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QB2', 'QZ', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QB2', 'QB4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QZ', 'QB4', 10.0))
|
|
||||||
|
|
||||||
#problem.add_point('QY', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('QC2', vector([1.0, 0.0]))
|
|
||||||
#problem.add_point('QZ', vector([0.0, 1.0]))
|
|
||||||
problem.add_point('QC4', vector([1.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('QY', 'QC2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QY', 'QZ', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QC2', 'QZ', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QC2', 'QC4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('QZ', 'QC4', 10.0))
|
|
||||||
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def hog1():
|
|
||||||
# double triangle with inter-angle (needs angle propagation)
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('A', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('B', vector([1.0, 0.0]))
|
|
||||||
problem.add_point('C', vector([1.0, 1.0]))
|
|
||||||
problem.add_point('D', vector([0.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('A', 'B', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('B', 'C', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('C', 'D', 10.0))
|
|
||||||
problem.add_constraint(AngleConstraint('B','A','C', math.pi / 8))
|
|
||||||
problem.add_constraint(AngleConstraint('B','A','D', math.pi / 4))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def hog2():
|
|
||||||
# several triangles with inter-angles (needs angle propagation)
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('M', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('A', vector([0.0, 1.0]))
|
|
||||||
problem.add_point('B', vector([1.0, 1.0]))
|
|
||||||
problem.add_point('C', vector([2.0, 1.0]))
|
|
||||||
problem.add_point('D', vector([3.0, 1.0]))
|
|
||||||
problem.add_point('E', vector([4.0, 1.0]))
|
|
||||||
problem.add_constraint(DistanceConstraint('A', 'M', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('A', 'E', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('B', 'E', 7.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('C', 'E', 6.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('D', 'E', 5.0))
|
|
||||||
problem.add_constraint(AngleConstraint('A','M','B', math.pi / 20))
|
|
||||||
problem.add_constraint(AngleConstraint('B','M','C', math.pi / 20))
|
|
||||||
problem.add_constraint(AngleConstraint('D','M','C', math.pi / 20))
|
|
||||||
problem.add_constraint(AngleConstraint('D','M','E', math.pi / 20))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def balloons():
|
|
||||||
# for testing angle propagation via balloon
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('A', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('B', vector([0.0, 1.0]))
|
|
||||||
problem.add_point('C', vector([1.0, 1.0]))
|
|
||||||
problem.add_point('D', vector([2.0, 1.0]))
|
|
||||||
problem.add_constraint(AngleConstraint('B','A','C', math.pi / 8))
|
|
||||||
problem.add_constraint(AngleConstraint('A','B','C', math.pi / 8))
|
|
||||||
problem.add_constraint(AngleConstraint('B','C','D', math.pi / 8))
|
|
||||||
problem.add_constraint(AngleConstraint('C','D','B', math.pi / 8))
|
|
||||||
problem.add_constraint(DistanceConstraint('A', 'D', 6.0))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def twoscisors():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('A', vector([0.0, 0.0]))
|
|
||||||
problem.add_point('B', vector([0.0, 1.0]))
|
|
||||||
problem.add_point('C', vector([1.0, 1.0]))
|
|
||||||
problem.add_point('D', vector([2.0, 1.0]))
|
|
||||||
problem.add_constraint(AngleConstraint('B','A','C', math.pi / 8))
|
|
||||||
problem.add_constraint(AngleConstraint('B','D','C', math.pi / 8))
|
|
||||||
problem.add_constraint(DistanceConstraint('A', 'B', 6.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('A', 'C', 6.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('D', 'B', 6.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('D', 'C', 6.0))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def selection_problem():
|
|
||||||
"""The double tetrahedron problem with selection constraints"""
|
|
||||||
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
|
||||||
|
|
||||||
#problem.add_constraint(SelectionConstraint(is_right_handed, ['v1','v2','v4','v5']))
|
|
||||||
problem.add_constraint(RightHandedConstraint('v1','v2','v4','v5'))
|
|
||||||
|
|
||||||
return problem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ------ 2D tests -------
|
|
||||||
|
|
||||||
def test_fix(n):
|
|
||||||
"""Test fix constraints"""
|
|
||||||
#diag_select("drplan._search_triangle")
|
|
||||||
|
|
||||||
print "generate a random 2D problem"
|
|
||||||
problem = random_problem_2D(n)
|
|
||||||
|
|
||||||
print "create dr planner"
|
|
||||||
drplanner = GeometericSolver(problem)
|
|
||||||
print "number of top clusters:", len(drplanner.dr.top_level())
|
|
||||||
#print "top clusters:", map(str, drplanner.dr.top_level())
|
|
||||||
|
|
||||||
cons = problem.cg.constraints()
|
|
||||||
dists = filter(lambda d: isinstance(d, DistanceConstraint), cons)
|
|
||||||
con = random.choice(dists)
|
|
||||||
print "remove distance", con
|
|
||||||
problem.rem_constraint(con)
|
|
||||||
print "number of top clusters:", len(drplanner.dr.top_level())
|
|
||||||
#print "top clusters:", map(str, drplanner.dr.top_level())
|
|
||||||
|
|
||||||
print "replace with two fixes"
|
|
||||||
v1 = con.variables()[0]
|
|
||||||
v2 = con.variables()[1]
|
|
||||||
f1 = FixConstraint(v1, problem.get_point(v1))
|
|
||||||
f2 = FixConstraint(v2, problem.get_point(v2))
|
|
||||||
problem.add_constraint(f1)
|
|
||||||
problem.add_constraint(f2)
|
|
||||||
print "number of top clusters:", len(drplanner.dr.top_level())
|
|
||||||
#print "top clusters:", map(str, drplanner.dr.top_level())
|
|
||||||
|
|
||||||
def test_fix2(n):
|
|
||||||
"""Test fix constraints"""
|
|
||||||
# diag_select("drplan.*")
|
|
||||||
print "generate a random 2D problem"
|
|
||||||
problem = random_problem_2D(n)
|
|
||||||
|
|
||||||
cons = problem.cg.constraints()
|
|
||||||
dists = filter(lambda d: isinstance(d, DistanceConstraint), cons)
|
|
||||||
con = random.choice(dists)
|
|
||||||
print "remove distance", con
|
|
||||||
problem.rem_constraint(con)
|
|
||||||
|
|
||||||
print "replace with two fixes"
|
|
||||||
v1 = con.variables()[0]
|
|
||||||
v2 = con.variables()[1]
|
|
||||||
f1 = FixConstraint(v1, problem.get_point(v1))
|
|
||||||
f2 = FixConstraint(v2, problem.get_point(v2))
|
|
||||||
problem.add_constraint(f1)
|
|
||||||
problem.add_constraint(f2)
|
|
||||||
|
|
||||||
print "create dr planner"
|
|
||||||
drplanner = GeometricSolver(problem)
|
|
||||||
print "number of top clusters:", len(drplanner.dr.top_level())
|
|
||||||
print "top clusters:", map(str, drplanner.dr.top_level())
|
|
||||||
|
|
||||||
|
|
||||||
def find_error(count, size, over_ratio):
|
|
||||||
"""Test solver by generating random problems"""
|
|
||||||
random.seed(1)
|
|
||||||
diag_select("xyzzy")
|
|
||||||
for i in range(0,count):
|
|
||||||
if random.random() > over_ratio:
|
|
||||||
if not test_random_wellconstrained(size):
|
|
||||||
print "failed wellconstrained problem #"+str(i)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
if not test_random_overconstrained(size):
|
|
||||||
print "failed overconstrained problem #"+str(i)
|
|
||||||
return
|
|
||||||
print "all tests passed"
|
|
||||||
|
|
||||||
|
|
||||||
def test_random_overconstrained(size):
|
|
||||||
# start with random well-constrained problem
|
|
||||||
problem = random_problem_2D(size, 0.0)
|
|
||||||
# add one random contraint
|
|
||||||
for i in range(100):
|
|
||||||
try:
|
|
||||||
add_random_constraint(problem, 0.5)
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if i == 99:
|
|
||||||
raise StandardError, "could not add extra constraint"
|
|
||||||
# test
|
|
||||||
try:
|
|
||||||
drplanner = GeometricSolver(problem)
|
|
||||||
ntop = len(drplanner.dr.top_level())
|
|
||||||
if ntop > 1:
|
|
||||||
message = "underconstrained"
|
|
||||||
check = False
|
|
||||||
elif ntop == 0:
|
|
||||||
message = "no top level"
|
|
||||||
check = False
|
|
||||||
else: # ntop == 1
|
|
||||||
top = drplanner.dr.top_level()[0]
|
|
||||||
if not top.overconstrained:
|
|
||||||
message = "well-constrained"
|
|
||||||
check = False
|
|
||||||
else:
|
|
||||||
check = True
|
|
||||||
except Exception, e:
|
|
||||||
message = "error:",e
|
|
||||||
check = False
|
|
||||||
#end try
|
|
||||||
if check == False:
|
|
||||||
print "--- problem ---"
|
|
||||||
print problem
|
|
||||||
print "--- diasgnostic messages ---"
|
|
||||||
diag_select("drplan")
|
|
||||||
drplanner = GeometricSolver(problem)
|
|
||||||
print "--- plan ---"
|
|
||||||
top = drplanner.dr.top_level()
|
|
||||||
print drplanner.dr
|
|
||||||
print "--- top level ---"
|
|
||||||
print len(top),"clusters:"
|
|
||||||
for cluster in drplanner.dr.top_level():
|
|
||||||
print cluster
|
|
||||||
print "--- conclusion ---"
|
|
||||||
print message
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def test_random_wellconstrained(size):
|
|
||||||
problem = random_problem_2D(size, 0.0)
|
|
||||||
try:
|
|
||||||
drplanner = GeometricSolver(problem)
|
|
||||||
ntop = len(drplanner.dr.top_level())
|
|
||||||
if ntop > 1:
|
|
||||||
message = "underconstrained"
|
|
||||||
check = False
|
|
||||||
elif ntop == 0:
|
|
||||||
message = "no top level"
|
|
||||||
check = False
|
|
||||||
else: # ntop == 1
|
|
||||||
top = drplanner.dr.top_level()[0]
|
|
||||||
if top.overconstrained:
|
|
||||||
message = "overconstrained"
|
|
||||||
check = False
|
|
||||||
else:
|
|
||||||
check = True
|
|
||||||
except Exception, e:
|
|
||||||
print "error in problem:",e
|
|
||||||
check = False
|
|
||||||
#end try
|
|
||||||
if check == False:
|
|
||||||
print "--- problem ---"
|
|
||||||
print problem
|
|
||||||
print "--- diasgnostic messages ---"
|
|
||||||
diag_select("drplan")
|
|
||||||
drplanner = GeometricSolver(problem)
|
|
||||||
top = drplanner.dr.top_level()
|
|
||||||
print "--- plan ---"
|
|
||||||
print drplanner.dr
|
|
||||||
print "--- top level ---"
|
|
||||||
print len(top),"clusters:"
|
|
||||||
for cluster in drplanner.dr.top_level():
|
|
||||||
print cluster
|
|
||||||
print "--- conclusion ---"
|
|
||||||
print message
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
#fed
|
|
||||||
|
|
||||||
def buggy1():
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
p0 = "P0"
|
|
||||||
p1 = "P1"
|
|
||||||
p2 = "P2"
|
|
||||||
p3 = "P3"
|
|
||||||
problem.add_point(p2,vector([4.2516273494524803, -9.510959969336783]))
|
|
||||||
problem.add_point(p3,vector([0.96994030830283862, -3.6416260233938491]))
|
|
||||||
problem.add_point(p0,vector([6.6635607149389386, -8.5894325593219882]))
|
|
||||||
problem.add_point(p1,vector([-0.06750282559988996, 6.6760454282229134]))
|
|
||||||
problem.add_constraint(AngleConstraint(p1,p3,p0,2.38643631762))
|
|
||||||
problem.add_constraint(DistanceConstraint(p2,p0,2.58198282856))
|
|
||||||
problem.add_constraint(AngleConstraint(p1,p0,p2,-1.52046205861))
|
|
||||||
problem.add_constraint(DistanceConstraint(p3,p1,10.3696977989))
|
|
||||||
problem.add_constraint(AngleConstraint(p3,p0,p1,0.440080782652))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def test_mergehogs():
|
|
||||||
diag_select(".")
|
|
||||||
problem = GeometricProblem(dimension=2)
|
|
||||||
problem.add_point('x',vector([0.0, 0.0]))
|
|
||||||
problem.add_point('a',vector([1.0, 0.0]))
|
|
||||||
problem.add_point('b',vector([0.0, 1.0]))
|
|
||||||
problem.add_point('c',vector([-1.0, 0.0]))
|
|
||||||
problem.add_point('d',vector([0.0, -1.0]))
|
|
||||||
problem.add_constraint(AngleConstraint('a','x','b', 30.0/180*math.pi))
|
|
||||||
problem.add_constraint(AngleConstraint('b','x','c', 30.0/180*math.pi))
|
|
||||||
problem.add_constraint(AngleConstraint('c','x','d', 30.0/180*math.pi))
|
|
||||||
solver = GeometricSolver(problem)
|
|
||||||
print solver.dr
|
|
||||||
for hog in solver.dr.hedgehogs():
|
|
||||||
conf = list(solver.mg.get(hog))[0]
|
|
||||||
print hog
|
|
||||||
print conf
|
|
||||||
print problem.verify(conf.map)
|
|
||||||
|
|
||||||
def test_non_triangular(n):
|
|
||||||
problem = random_problem_2D(n)
|
|
||||||
print "before:"
|
|
||||||
print problem
|
|
||||||
randomize_angles(problem)
|
|
||||||
print "after:"
|
|
||||||
print problem
|
|
||||||
test(problem)
|
|
||||||
|
|
||||||
|
|
||||||
# ----------- 3d tests ----------
|
|
||||||
|
|
||||||
def test_ada_3d():
|
|
||||||
problem = ada_3d_problem()
|
|
||||||
diag_select("nothing")
|
|
||||||
print "problem:"
|
|
||||||
print problem
|
|
||||||
solver = GeometricSolver(problem)
|
|
||||||
print "drplan:"
|
|
||||||
print solver.dr
|
|
||||||
print "number of top-level rigids:",len(solver.dr.top_level())
|
|
||||||
result = solver.get_result()
|
|
||||||
print "result:"
|
|
||||||
print result
|
|
||||||
print "result is",result.flag, "with", len(result.solutions),"solutions"
|
|
||||||
check = True
|
|
||||||
if len(result.solutions) == 0:
|
|
||||||
check = False
|
|
||||||
diag_select(".*")
|
|
||||||
for sol in result.solutions:
|
|
||||||
print "solution:",sol
|
|
||||||
check = check and problem.verify(sol)
|
|
||||||
diag_select("nothing")
|
|
||||||
if check:
|
|
||||||
print "all solutions valid"
|
|
||||||
else:
|
|
||||||
print "INVALID"
|
|
||||||
|
|
||||||
|
|
||||||
# ------- generic test -------
|
|
||||||
|
|
||||||
def test(problem):
|
|
||||||
"""Test solver on a given problem"""
|
|
||||||
#diag_select(".*")
|
|
||||||
print "problem:"
|
|
||||||
print problem
|
|
||||||
print "Solving..."
|
|
||||||
solver = GeometricSolver(problem)
|
|
||||||
print "...done"
|
|
||||||
print "drplan:"
|
|
||||||
print solver.dr
|
|
||||||
print "top-level rigids:",list(solver.dr.top_level())
|
|
||||||
result = solver.get_result()
|
|
||||||
print "result:"
|
|
||||||
print result
|
|
||||||
print "result is",result.flag, "with", len(result.solutions),"solutions"
|
|
||||||
check = True
|
|
||||||
if len(result.solutions) == 0:
|
|
||||||
check = False
|
|
||||||
diag_select("(GeometricProblem.verify)|(satisfied)")
|
|
||||||
for sol in result.solutions:
|
|
||||||
print "solution:",sol
|
|
||||||
check = check and problem.verify(sol)
|
|
||||||
if check:
|
|
||||||
print "all solutions valid"
|
|
||||||
else:
|
|
||||||
print "INVALID"
|
|
||||||
|
|
||||||
# ----- what to test today -------
|
|
||||||
|
|
||||||
#if __name__ == "__main__":
|
|
||||||
# find_error(1000, 4)
|
|
||||||
|
|
||||||
#if __name__ == "__main__":
|
|
||||||
# test(random_problem_2D(4, 0.0))
|
|
||||||
|
|
||||||
#if __name__ == "__main__":
|
|
||||||
# diag_select("(.*Method)|(GeometricProblem.verify)")
|
|
||||||
# test(random_AAD())
|
|
||||||
|
|
||||||
#if __name__ == "__main__":
|
|
||||||
# #diag_select("(.*Method)|(GeometricProblem.verify)")
|
|
||||||
# diag_select("drplan")
|
|
||||||
# test(propagation_problem())
|
|
||||||
|
|
||||||
#if __name__ == "__main__":
|
|
||||||
# diag_select("(GeometricProblem.verify)")
|
|
||||||
# test(balloon_problem())
|
|
||||||
|
|
||||||
# create statistics for solving time
|
|
||||||
def stats_solving():
|
|
||||||
print "size \t # \t time \t result"
|
|
||||||
for size in range(4,31):
|
|
||||||
for i in range(1,10):
|
|
||||||
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
|
||||||
t1 = time()
|
|
||||||
solver = GeometricSolver(problem)
|
|
||||||
result = solver.get_status()
|
|
||||||
t2 = time()
|
|
||||||
t = t2-t1
|
|
||||||
print size,"\t",i,"\t",t,"\t",result
|
|
||||||
|
|
||||||
# create statistics for incremental solving time
|
|
||||||
def stats_incremental():
|
|
||||||
#diag_select("clsolver.remove")
|
|
||||||
print "size \t # \t time \t result"
|
|
||||||
for size in range(4,31):
|
|
||||||
for i in range(1,10):
|
|
||||||
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
|
||||||
solver = GeometricSolver(problem)
|
|
||||||
t1 = time()
|
|
||||||
constraint = random.choice(problem.cg.constraints())
|
|
||||||
problem.rem_constraint(constraint)
|
|
||||||
problem.add_constraint(constraint)
|
|
||||||
result = solver.get_status()
|
|
||||||
t2 = time()
|
|
||||||
t = t2-t1
|
|
||||||
print size,"\t",i,"\t",t,"\t",result
|
|
||||||
|
|
||||||
# create statistics for parametric change
|
|
||||||
def stats_parametric_incremental():
|
|
||||||
#diag_select("clsolver.remove")
|
|
||||||
print "size \t # \t time \t result"
|
|
||||||
for size in range(4,31):
|
|
||||||
for i in range(1,10):
|
|
||||||
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
|
||||||
solver = GeometricSolver(problem)
|
|
||||||
constraint = random.choice(problem.cg.constraints())
|
|
||||||
#problem.rem_constraint(constraint)
|
|
||||||
#problem.add_constraint(constraint)
|
|
||||||
#problem.rem_constraint(constraint)
|
|
||||||
#problem.add_constraint(constraint)
|
|
||||||
t1 = time()
|
|
||||||
#problem.rem_constraint(constraint)
|
|
||||||
#problem.add_constraint(constraint)
|
|
||||||
#constraint.set_parameter(constraint.get_parameter())
|
|
||||||
result = solver.get_status()
|
|
||||||
t2 = time()
|
|
||||||
t = t2-t1
|
|
||||||
print size,"\t",i,"\t",t,"\t",result
|
|
||||||
|
|
||||||
# create statistics for parametric change
|
|
||||||
def stats_parametric():
|
|
||||||
#diag_select("clsolver.remove")
|
|
||||||
print "size \t # \t time \t result"
|
|
||||||
for size in range(4,31):
|
|
||||||
for i in range(1,10):
|
|
||||||
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
|
||||||
solver = GeometricSolver(problem)
|
|
||||||
constraint = random.choice(problem.cg.constraints())
|
|
||||||
t1 = time()
|
|
||||||
constraint.set_parameter(constraint.get_parameter())
|
|
||||||
result = solver.get_status()
|
|
||||||
t2 = time()
|
|
||||||
t = t2-t1
|
|
||||||
print size,"\t",i,"\t",t,"\t",result
|
|
||||||
|
|
||||||
def runstats():
|
|
||||||
stats_solving()
|
|
||||||
stats_incremental()
|
|
||||||
stats_parametric_incremental()
|
|
||||||
stats_parametric()
|
|
||||||
|
|
||||||
def selection_test():
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
|
|
||||||
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
|
||||||
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
|
||||||
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
|
||||||
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
|
||||||
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
|
||||||
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
|
||||||
|
|
||||||
s1 = SelectionConstraint(is_right_handed, ['v1','v2','v4','v5'])
|
|
||||||
|
|
||||||
# add selection con
|
|
||||||
problem.add_constraint(s1)
|
|
||||||
|
|
||||||
# solve
|
|
||||||
solver = GeometricSolver(problem, False)
|
|
||||||
print len(solver.get_solutions()), "solutions"
|
|
||||||
|
|
||||||
# remove and add constraint
|
|
||||||
print "removing selection-constraint"
|
|
||||||
problem.rem_constraint(s1)
|
|
||||||
|
|
||||||
# solve again
|
|
||||||
print len(solver.get_solutions()), "solutions"
|
|
||||||
|
|
||||||
# remove and add constraint
|
|
||||||
print "re-adding selection constraint"
|
|
||||||
problem.add_constraint(s1)
|
|
||||||
|
|
||||||
# solve again
|
|
||||||
print len(solver.get_solutions()), "solutions"
|
|
||||||
|
|
||||||
# remove distance
|
|
||||||
print "removing and re-adding distance v1-v5"
|
|
||||||
problem.rem_constraint(problem.get_distance("v1","v5"))
|
|
||||||
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
|
||||||
|
|
||||||
# solve again
|
|
||||||
print len(solver.get_solutions()), "solutions"
|
|
||||||
|
|
||||||
|
|
||||||
def test3d():
|
|
||||||
#diag_select("clsolver")
|
|
||||||
#test(double_tetrahedron_problem())
|
|
||||||
#test(ada_tetrahedron_problem())
|
|
||||||
#test(double_banana_problem())
|
|
||||||
#test(double_banana_plus_one_problem())
|
|
||||||
#test(random_triangular_problem_3D(10,10.0,0.0,0.5))
|
|
||||||
#test(random_distance_problem_3D(10,1.0,0.0))
|
|
||||||
#test(fix1_problem_3d())
|
|
||||||
test(fix2_problem_3d())
|
|
||||||
#test(fix3_problem_3d())
|
|
||||||
#diag_select("SelectionMethod.*")
|
|
||||||
#test(selection_problem(),False)
|
|
||||||
#selection_test()
|
|
||||||
#test(overconstrained_tetra())
|
|
||||||
#test(diamond_3d(),False)
|
|
||||||
|
|
||||||
def test2d():
|
|
||||||
#diag_select("clsolver")
|
|
||||||
#test(ddd_problem())
|
|
||||||
#test(double_triangle())
|
|
||||||
test(triple_double_triangle())
|
|
||||||
#test(dad_problem())
|
|
||||||
#test(add_problem())
|
|
||||||
#test(ada_problem())
|
|
||||||
#test(aad_problem())
|
|
||||||
|
|
||||||
def line_problem():
|
|
||||||
"""A problem with a fix constraint"""
|
|
||||||
problem = GeometricProblem(dimension=3)
|
|
||||||
problem.add_variable(Point('p1'),vector([0.0, 0.0, 0.0]))
|
|
||||||
problem.add_variable(Line('l1'),vector([0.0, 0.0, 0.0, 1.0, 1.0, 1.0]))
|
|
||||||
problem.add_constraint(CoincidenceConstraint(Point('p1'), Line('l1')))
|
|
||||||
return problem
|
|
||||||
|
|
||||||
def test_line():
|
|
||||||
test(line_problem())
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
test_line()
|
|
485
test/test_2d.py
Normal file
485
test/test_2d.py
Normal file
|
@ -0,0 +1,485 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""This module provides some tests for the GeoSolver.
|
||||||
|
These test are for 2D solving.
|
||||||
|
The tests are also simple examples of how to use of the GeomSolver API"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
from test_generic import test
|
||||||
|
from geosolver.geometric import GeometricProblem, GeometricSolver, DistanceConstraint, AngleConstraint, FixConstraint
|
||||||
|
from geosolver.vector import vector
|
||||||
|
from geosolver.randomproblem import random_problem_2D
|
||||||
|
from geosolver.diagnostic import diag_select, diag_print
|
||||||
|
from geosolver.intersections import distance_2p, angle_3p
|
||||||
|
|
||||||
|
# -------- 2D problems
|
||||||
|
|
||||||
|
def ddd_problem():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v3',distance_2p(problem.get_point('v1'), problem.get_point('v3'))))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2','v3',distance_2p(problem.get_point('v2'), problem.get_point('v3'))))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def dad_problem():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v2',
|
||||||
|
distance_2p(problem.get_point('v1'), problem.get_point('v2'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2','v3',
|
||||||
|
distance_2p(problem.get_point('v2'), problem.get_point('v3'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('v1','v2','v3',
|
||||||
|
angle_3p(problem.get_point('v1'), problem.get_point('v2'), problem.get_point('v3'))
|
||||||
|
))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def add_problem():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v2',
|
||||||
|
distance_2p(problem.get_point('v1'), problem.get_point('v2'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2','v3',
|
||||||
|
distance_2p(problem.get_point('v2'), problem.get_point('v3'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('v3','v1','v2',
|
||||||
|
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
||||||
|
))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
def aad_problem():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
||||||
|
problem.add_constraint(AngleConstraint('v2', 'v3', 'v1',
|
||||||
|
angle_3p(problem.get_point('v2'), problem.get_point('v3'), problem.get_point('v1'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('v3', 'v1', 'v2',
|
||||||
|
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
||||||
|
))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def ada_problem():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
||||||
|
problem.add_constraint(AngleConstraint('v3', 'v1', 'v2',
|
||||||
|
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('v1', 'v2', 'v3',
|
||||||
|
angle_3p(problem.get_point('v1'), problem.get_point('v2'), problem.get_point('v3'))
|
||||||
|
))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def propagation_problem():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v4', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v5', vector([random.random() for i in [1,2]]))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v2',
|
||||||
|
distance_2p(problem.get_point('v1'), problem.get_point('v2'))
|
||||||
|
))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v3',
|
||||||
|
distance_2p(problem.get_point('v1'), problem.get_point('v3'))
|
||||||
|
))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v2','v3',
|
||||||
|
distance_2p(problem.get_point('v2'), problem.get_point('v3'))
|
||||||
|
))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v2','v4',
|
||||||
|
distance_2p(problem.get_point('v2'), problem.get_point('v4'))
|
||||||
|
))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v5',
|
||||||
|
distance_2p(problem.get_point('v1'), problem.get_point('v5'))
|
||||||
|
))
|
||||||
|
|
||||||
|
problem.add_constraint(AngleConstraint('v3', 'v1', 'v4',
|
||||||
|
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v4'))
|
||||||
|
))
|
||||||
|
|
||||||
|
problem.add_constraint(AngleConstraint('v3', 'v2', 'v5',
|
||||||
|
angle_3p(problem.get_point('v3'), problem.get_point('v2'), problem.get_point('v5'))
|
||||||
|
))
|
||||||
|
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
def balloon_problem():
|
||||||
|
"""test angle propagation via balloon"""
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('A', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('B', vector([1.0, -1.0]))
|
||||||
|
problem.add_point('C', vector([1.0, +1.0]))
|
||||||
|
problem.add_point('D', vector([2.0, 0.0]))
|
||||||
|
problem.add_constraint(AngleConstraint('B','A','C',
|
||||||
|
angle_3p(problem.get_point('B'), problem.get_point('A'), problem.get_point('C'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('A','B','C',
|
||||||
|
angle_3p(problem.get_point('A'), problem.get_point('B'), problem.get_point('C'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('B','C','D',
|
||||||
|
angle_3p(problem.get_point('B'), problem.get_point('C'), problem.get_point('D'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('C','D','B',
|
||||||
|
angle_3p(problem.get_point('C'), problem.get_point('D'), problem.get_point('B'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(DistanceConstraint('A', 'D', 6.0))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def double_triangle():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0]))
|
||||||
|
problem.add_point('v4', vector([1.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def triple_double_triangle():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('QX', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('QA2', vector([1.0, 0.0]))
|
||||||
|
problem.add_point('QA3', vector([0.0, 1.0]))
|
||||||
|
problem.add_point('QY', vector([1.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('QX', 'QA2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QX', 'QA3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QA2', 'QA3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QA2', 'QY', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QA3', 'QY', 10.0))
|
||||||
|
|
||||||
|
#problem.add_point('QX', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('QB2', vector([1.0, 0.0]))
|
||||||
|
problem.add_point('QZ', vector([0.0, 1.0]))
|
||||||
|
problem.add_point('QB4', vector([1.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('QX', 'QB2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QX', 'QZ', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QB2', 'QZ', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QB2', 'QB4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QZ', 'QB4', 10.0))
|
||||||
|
|
||||||
|
#problem.add_point('QY', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('QC2', vector([1.0, 0.0]))
|
||||||
|
#problem.add_point('QZ', vector([0.0, 1.0]))
|
||||||
|
problem.add_point('QC4', vector([1.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('QY', 'QC2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QY', 'QZ', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QC2', 'QZ', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QC2', 'QC4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('QZ', 'QC4', 10.0))
|
||||||
|
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def hog1():
|
||||||
|
# double triangle with inter-angle (needs angle propagation)
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('A', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('B', vector([1.0, 0.0]))
|
||||||
|
problem.add_point('C', vector([1.0, 1.0]))
|
||||||
|
problem.add_point('D', vector([0.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('A', 'B', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('B', 'C', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('C', 'D', 10.0))
|
||||||
|
problem.add_constraint(AngleConstraint('B','A','C', math.pi / 8))
|
||||||
|
problem.add_constraint(AngleConstraint('B','A','D', math.pi / 4))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def hog2():
|
||||||
|
# several triangles with inter-angles (needs angle propagation)
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('M', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('A', vector([0.0, 1.0]))
|
||||||
|
problem.add_point('B', vector([1.0, 1.0]))
|
||||||
|
problem.add_point('C', vector([2.0, 1.0]))
|
||||||
|
problem.add_point('D', vector([3.0, 1.0]))
|
||||||
|
problem.add_point('E', vector([4.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('A', 'M', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('A', 'E', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('B', 'E', 7.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('C', 'E', 6.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('D', 'E', 5.0))
|
||||||
|
problem.add_constraint(AngleConstraint('A','M','B', math.pi / 20))
|
||||||
|
problem.add_constraint(AngleConstraint('B','M','C', math.pi / 20))
|
||||||
|
problem.add_constraint(AngleConstraint('D','M','C', math.pi / 20))
|
||||||
|
problem.add_constraint(AngleConstraint('D','M','E', math.pi / 20))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def balloons():
|
||||||
|
# for testing angle propagation via balloon
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('A', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('B', vector([0.0, 1.0]))
|
||||||
|
problem.add_point('C', vector([1.0, 1.0]))
|
||||||
|
problem.add_point('D', vector([2.0, 1.0]))
|
||||||
|
problem.add_constraint(AngleConstraint('B','A','C', math.pi / 8))
|
||||||
|
problem.add_constraint(AngleConstraint('A','B','C', math.pi / 8))
|
||||||
|
problem.add_constraint(AngleConstraint('B','C','D', math.pi / 8))
|
||||||
|
problem.add_constraint(AngleConstraint('C','D','B', math.pi / 8))
|
||||||
|
problem.add_constraint(DistanceConstraint('A', 'D', 6.0))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def twoscisors():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('A', vector([0.0, 0.0]))
|
||||||
|
problem.add_point('B', vector([0.0, 1.0]))
|
||||||
|
problem.add_point('C', vector([1.0, 1.0]))
|
||||||
|
problem.add_point('D', vector([2.0, 1.0]))
|
||||||
|
problem.add_constraint(AngleConstraint('B','A','C', math.pi / 8))
|
||||||
|
problem.add_constraint(AngleConstraint('B','D','C', math.pi / 8))
|
||||||
|
problem.add_constraint(DistanceConstraint('A', 'B', 6.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('A', 'C', 6.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('D', 'B', 6.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('D', 'C', 6.0))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
# ------ 2D tests -------
|
||||||
|
|
||||||
|
def test_fix(n):
|
||||||
|
"""Test fix constraints"""
|
||||||
|
#diag_select("drplan._search_triangle")
|
||||||
|
|
||||||
|
print "generate a random 2D problem"
|
||||||
|
problem = random_problem_2D(n)
|
||||||
|
|
||||||
|
print "create dr planner"
|
||||||
|
drplanner = GeometericSolver(problem)
|
||||||
|
print "number of top clusters:", len(drplanner.dr.top_level())
|
||||||
|
#print "top clusters:", map(str, drplanner.dr.top_level())
|
||||||
|
|
||||||
|
cons = problem.cg.constraints()
|
||||||
|
dists = filter(lambda d: isinstance(d, DistanceConstraint), cons)
|
||||||
|
con = random.choice(dists)
|
||||||
|
print "remove distance", con
|
||||||
|
problem.rem_constraint(con)
|
||||||
|
print "number of top clusters:", len(drplanner.dr.top_level())
|
||||||
|
#print "top clusters:", map(str, drplanner.dr.top_level())
|
||||||
|
|
||||||
|
print "replace with two fixes"
|
||||||
|
v1 = con.variables()[0]
|
||||||
|
v2 = con.variables()[1]
|
||||||
|
f1 = FixConstraint(v1, problem.get_point(v1))
|
||||||
|
f2 = FixConstraint(v2, problem.get_point(v2))
|
||||||
|
problem.add_constraint(f1)
|
||||||
|
problem.add_constraint(f2)
|
||||||
|
print "number of top clusters:", len(drplanner.dr.top_level())
|
||||||
|
#print "top clusters:", map(str, drplanner.dr.top_level())
|
||||||
|
|
||||||
|
def test_fix2(n):
|
||||||
|
"""Test fix constraints"""
|
||||||
|
# diag_select("drplan.*")
|
||||||
|
print "generate a random 2D problem"
|
||||||
|
problem = random_problem_2D(n)
|
||||||
|
|
||||||
|
cons = problem.cg.constraints()
|
||||||
|
dists = filter(lambda d: isinstance(d, DistanceConstraint), cons)
|
||||||
|
con = random.choice(dists)
|
||||||
|
print "remove distance", con
|
||||||
|
problem.rem_constraint(con)
|
||||||
|
|
||||||
|
print "replace with two fixes"
|
||||||
|
v1 = con.variables()[0]
|
||||||
|
v2 = con.variables()[1]
|
||||||
|
f1 = FixConstraint(v1, problem.get_point(v1))
|
||||||
|
f2 = FixConstraint(v2, problem.get_point(v2))
|
||||||
|
problem.add_constraint(f1)
|
||||||
|
problem.add_constraint(f2)
|
||||||
|
|
||||||
|
print "create dr planner"
|
||||||
|
drplanner = GeometricSolver(problem)
|
||||||
|
print "number of top clusters:", len(drplanner.dr.top_level())
|
||||||
|
print "top clusters:", map(str, drplanner.dr.top_level())
|
||||||
|
|
||||||
|
|
||||||
|
def find_error(count, size, over_ratio):
|
||||||
|
"""Test solver by generating random problems"""
|
||||||
|
random.seed(1)
|
||||||
|
diag_select("xyzzy")
|
||||||
|
for i in range(0,count):
|
||||||
|
if random.random() > over_ratio:
|
||||||
|
if not test_random_wellconstrained(size):
|
||||||
|
print "failed wellconstrained problem #"+str(i)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if not test_random_overconstrained(size):
|
||||||
|
print "failed overconstrained problem #"+str(i)
|
||||||
|
return
|
||||||
|
print "all tests passed"
|
||||||
|
|
||||||
|
|
||||||
|
def test_random_overconstrained(size):
|
||||||
|
# start with random well-constrained problem
|
||||||
|
problem = random_problem_2D(size, 0.0)
|
||||||
|
# add one random contraint
|
||||||
|
for i in range(100):
|
||||||
|
try:
|
||||||
|
add_random_constraint(problem, 0.5)
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if i == 99:
|
||||||
|
raise StandardError, "could not add extra constraint"
|
||||||
|
# test
|
||||||
|
try:
|
||||||
|
drplanner = GeometricSolver(problem)
|
||||||
|
ntop = len(drplanner.dr.top_level())
|
||||||
|
if ntop > 1:
|
||||||
|
message = "underconstrained"
|
||||||
|
check = False
|
||||||
|
elif ntop == 0:
|
||||||
|
message = "no top level"
|
||||||
|
check = False
|
||||||
|
else: # ntop == 1
|
||||||
|
top = drplanner.dr.top_level()[0]
|
||||||
|
if not top.overconstrained:
|
||||||
|
message = "well-constrained"
|
||||||
|
check = False
|
||||||
|
else:
|
||||||
|
check = True
|
||||||
|
except Exception, e:
|
||||||
|
message = "error:",e
|
||||||
|
check = False
|
||||||
|
#end try
|
||||||
|
if check == False:
|
||||||
|
print "--- problem ---"
|
||||||
|
print problem
|
||||||
|
print "--- diasgnostic messages ---"
|
||||||
|
diag_select("drplan")
|
||||||
|
drplanner = GeometricSolver(problem)
|
||||||
|
print "--- plan ---"
|
||||||
|
top = drplanner.dr.top_level()
|
||||||
|
print drplanner.dr
|
||||||
|
print "--- top level ---"
|
||||||
|
print len(top),"clusters:"
|
||||||
|
for cluster in drplanner.dr.top_level():
|
||||||
|
print cluster
|
||||||
|
print "--- conclusion ---"
|
||||||
|
print message
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def test_random_wellconstrained(size):
|
||||||
|
problem = random_problem_2D(size, 0.0)
|
||||||
|
try:
|
||||||
|
drplanner = GeometricSolver(problem)
|
||||||
|
ntop = len(drplanner.dr.top_level())
|
||||||
|
if ntop > 1:
|
||||||
|
message = "underconstrained"
|
||||||
|
check = False
|
||||||
|
elif ntop == 0:
|
||||||
|
message = "no top level"
|
||||||
|
check = False
|
||||||
|
else: # ntop == 1
|
||||||
|
top = drplanner.dr.top_level()[0]
|
||||||
|
if top.overconstrained:
|
||||||
|
message = "overconstrained"
|
||||||
|
check = False
|
||||||
|
else:
|
||||||
|
check = True
|
||||||
|
except Exception, e:
|
||||||
|
print "error in problem:",e
|
||||||
|
check = False
|
||||||
|
#end try
|
||||||
|
if check == False:
|
||||||
|
print "--- problem ---"
|
||||||
|
print problem
|
||||||
|
print "--- diasgnostic messages ---"
|
||||||
|
diag_select("drplan")
|
||||||
|
drplanner = GeometricSolver(problem)
|
||||||
|
top = drplanner.dr.top_level()
|
||||||
|
print "--- plan ---"
|
||||||
|
print drplanner.dr
|
||||||
|
print "--- top level ---"
|
||||||
|
print len(top),"clusters:"
|
||||||
|
for cluster in drplanner.dr.top_level():
|
||||||
|
print cluster
|
||||||
|
print "--- conclusion ---"
|
||||||
|
print message
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
#fed
|
||||||
|
|
||||||
|
def buggy1():
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
p0 = "P0"
|
||||||
|
p1 = "P1"
|
||||||
|
p2 = "P2"
|
||||||
|
p3 = "P3"
|
||||||
|
problem.add_point(p2,vector([4.2516273494524803, -9.510959969336783]))
|
||||||
|
problem.add_point(p3,vector([0.96994030830283862, -3.6416260233938491]))
|
||||||
|
problem.add_point(p0,vector([6.6635607149389386, -8.5894325593219882]))
|
||||||
|
problem.add_point(p1,vector([-0.06750282559988996, 6.6760454282229134]))
|
||||||
|
problem.add_constraint(AngleConstraint(p1,p3,p0,2.38643631762))
|
||||||
|
problem.add_constraint(DistanceConstraint(p2,p0,2.58198282856))
|
||||||
|
problem.add_constraint(AngleConstraint(p1,p0,p2,-1.52046205861))
|
||||||
|
problem.add_constraint(DistanceConstraint(p3,p1,10.3696977989))
|
||||||
|
problem.add_constraint(AngleConstraint(p3,p0,p1,0.440080782652))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def test_mergehogs():
|
||||||
|
diag_select(".")
|
||||||
|
problem = GeometricProblem(dimension=2)
|
||||||
|
problem.add_point('x',vector([0.0, 0.0]))
|
||||||
|
problem.add_point('a',vector([1.0, 0.0]))
|
||||||
|
problem.add_point('b',vector([0.0, 1.0]))
|
||||||
|
problem.add_point('c',vector([-1.0, 0.0]))
|
||||||
|
problem.add_point('d',vector([0.0, -1.0]))
|
||||||
|
problem.add_constraint(AngleConstraint('a','x','b', 30.0/180*math.pi))
|
||||||
|
problem.add_constraint(AngleConstraint('b','x','c', 30.0/180*math.pi))
|
||||||
|
problem.add_constraint(AngleConstraint('c','x','d', 30.0/180*math.pi))
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
print solver.dr
|
||||||
|
for hog in solver.dr.hedgehogs():
|
||||||
|
conf = list(solver.mg.get(hog))[0]
|
||||||
|
print hog
|
||||||
|
print conf
|
||||||
|
print problem.verify(conf.map)
|
||||||
|
|
||||||
|
def test_non_triangular(n):
|
||||||
|
problem = random_problem_2D(n)
|
||||||
|
print "before:"
|
||||||
|
print problem
|
||||||
|
randomize_angles(problem)
|
||||||
|
print "after:"
|
||||||
|
print problem
|
||||||
|
test(problem)
|
||||||
|
|
||||||
|
def test2d():
|
||||||
|
#diag_select("clsolver")
|
||||||
|
test(ddd_problem())
|
||||||
|
test(double_triangle())
|
||||||
|
test(triple_double_triangle())
|
||||||
|
test(dad_problem())
|
||||||
|
test(add_problem())
|
||||||
|
test(ada_problem())
|
||||||
|
test(aad_problem())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test2d()
|
375
test/test_3d.py
Normal file
375
test/test_3d.py
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""This module provides some tests for the GeoSolver.
|
||||||
|
These tests are concerned with 3D solving.
|
||||||
|
The tests are also simple examples of how to use of the GeomSolver API"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
import math
|
||||||
|
from test_generic import test
|
||||||
|
from geosolver.geometric import GeometricProblem, GeometricSolver, DistanceConstraint,AngleConstraint, FixConstraint,RightHandedConstraint
|
||||||
|
from geosolver.vector import vector
|
||||||
|
from geosolver.randomproblem import random_triangular_problem_3D, random_distance_problem_3D
|
||||||
|
from geosolver.diagnostic import diag_select, diag_print
|
||||||
|
from geosolver.intersections import distance_2p, angle_3p
|
||||||
|
|
||||||
|
# ---------- 3D problems -----
|
||||||
|
|
||||||
|
def fix3_problem_3d():
|
||||||
|
"""A problem with a fix constraint"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.0, 0.0, 1.0]))
|
||||||
|
#problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
#problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
#problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(FixConstraint('v1', vector([0.0,0.0,0.0])))
|
||||||
|
problem.add_constraint(FixConstraint('v2', vector([10.0,0.0,0.0])))
|
||||||
|
problem.add_constraint(FixConstraint('v3', vector([5.0,5.0,0.0])))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def fix2_problem_3d():
|
||||||
|
"""A problem with a fix constraint"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.0, 0.0, 1.0]))
|
||||||
|
#problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(FixConstraint('v1', vector([0.0,0.0,0.0])))
|
||||||
|
problem.add_constraint(FixConstraint('v2', vector([10.0,0.0,0.0])))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def fix1_problem_3d():
|
||||||
|
"""A problem with a fix constraint"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.0, 0.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(FixConstraint('v1', vector([0.0,0.0,0.0])))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def double_banana_problem():
|
||||||
|
"""The double banana problem"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
||||||
|
|
||||||
|
problem.add_point('w1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('w2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('w3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'w2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'w3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w2', 'w3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w3', 'v5', 10.0))
|
||||||
|
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def double_banana_plus_one_problem():
|
||||||
|
"""The double banana problem, plus one constraint (well-constrained)"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
||||||
|
|
||||||
|
problem.add_point('w1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('w2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('w3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'w2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'w3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w2', 'w3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('w3', 'v5', 10.0))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'w1', 10.0))
|
||||||
|
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
def double_tetrahedron_problem():
|
||||||
|
"""The double tetrahedron problem"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
def dad_tetrahedron_problem():
|
||||||
|
"""The double tetrahedron problem with an angle"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(AngleConstraint('v2', 'v1','v3', 60.0*math.pi/180.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def ada_tetrahedron_problem():
|
||||||
|
"""The double tetrahedron problem with an angle"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(AngleConstraint('v3', 'v1','v2', 60.0*math.pi/180.0))
|
||||||
|
problem.add_constraint(AngleConstraint('v1', 'v2','v3', 60.0*math.pi/180.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def ada_3d_problem():
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v2', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_point('v3', vector([random.random() for i in [1,2]]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1','v2',distance_2p(problem.get_point('v1'), problem.get_point('v2'))))
|
||||||
|
problem.add_constraint(AngleConstraint('v3', 'v1', 'v2',
|
||||||
|
angle_3p(problem.get_point('v3'), problem.get_point('v1'), problem.get_point('v2'))
|
||||||
|
))
|
||||||
|
problem.add_constraint(AngleConstraint('v1', 'v2', 'v3',
|
||||||
|
angle_3p(problem.get_point('v1'), problem.get_point('v2'), problem.get_point('v3'))
|
||||||
|
))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def overconstrained_tetra():
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
# overconstrain me!
|
||||||
|
problem.add_constraint(AngleConstraint('v1', 'v2', 'v3', math.pi/3))
|
||||||
|
#problem.add_constraint(AngleConstraint('v1', 'v2', 'v3', math.pi/4))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def diamond_3d():
|
||||||
|
"""creates a diamond shape with point 'v1'...'v4' in 3D with one solution"""
|
||||||
|
# Following should be well-constraint, gives underconstrained (need extra rule/pattern)
|
||||||
|
L=10.0
|
||||||
|
problem = GeometricProblem(dimension=3, use_prototype=False) # no prototype based selection
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([-5.0, 5.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([5.0, 5.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.0, 10.0, 0.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', L))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', L))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', L))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', L))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', L))
|
||||||
|
# this bit of code constrains the points v1...v4 in a plane with point p above it
|
||||||
|
problem.add_point('p', vector([0.0, 0.0, 1.0]))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'p', 1.0))
|
||||||
|
problem.add_constraint(AngleConstraint('v2','v1','p', math.pi/2))
|
||||||
|
problem.add_constraint(AngleConstraint('v3','v1','p', math.pi/2))
|
||||||
|
problem.add_constraint(AngleConstraint('v4','v1','p', math.pi/2))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
# ----------- 3d tests ----------
|
||||||
|
|
||||||
|
def test_ada_3d():
|
||||||
|
problem = ada_3d_problem()
|
||||||
|
diag_select("nothing")
|
||||||
|
print "problem:"
|
||||||
|
print problem
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
print "drplan:"
|
||||||
|
print solver.dr
|
||||||
|
print "number of top-level rigids:",len(solver.dr.top_level())
|
||||||
|
result = solver.get_result()
|
||||||
|
print "result:"
|
||||||
|
print result
|
||||||
|
print "result is",result.flag, "with", len(result.solutions),"solutions"
|
||||||
|
check = True
|
||||||
|
if len(result.solutions) == 0:
|
||||||
|
check = False
|
||||||
|
diag_select(".*")
|
||||||
|
for sol in result.solutions:
|
||||||
|
print "solution:",sol
|
||||||
|
check = check and problem.verify(sol)
|
||||||
|
diag_select("nothing")
|
||||||
|
if check:
|
||||||
|
print "all solutions valid"
|
||||||
|
else:
|
||||||
|
print "INVALID"
|
||||||
|
|
||||||
|
def selection_test():
|
||||||
|
problem = GeometricProblem(dimension=3,use_prototype=False)
|
||||||
|
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
||||||
|
|
||||||
|
s1 = RightHandedConstraint('v1','v2','v4','v5')
|
||||||
|
|
||||||
|
# add selection con
|
||||||
|
problem.add_constraint(s1)
|
||||||
|
|
||||||
|
# solve
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
print len(solver.get_solutions()), "solutions"
|
||||||
|
|
||||||
|
# remove and add constraint
|
||||||
|
print "removing selection-constraint"
|
||||||
|
problem.rem_constraint(s1)
|
||||||
|
|
||||||
|
# solve again
|
||||||
|
print len(solver.get_solutions()), "solutions"
|
||||||
|
|
||||||
|
# remove and add constraint
|
||||||
|
print "re-adding selection constraint"
|
||||||
|
problem.add_constraint(s1)
|
||||||
|
|
||||||
|
# solve again
|
||||||
|
print len(solver.get_solutions()), "solutions"
|
||||||
|
|
||||||
|
# remove distance
|
||||||
|
print "removing and re-adding distance v1-v5"
|
||||||
|
problem.rem_constraint(problem.get_distance("v1","v5"))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
|
||||||
|
# solve again
|
||||||
|
print len(solver.get_solutions()), "solutions"
|
||||||
|
|
||||||
|
def selection_problem():
|
||||||
|
"""The double tetrahedron problem with selection constraints"""
|
||||||
|
|
||||||
|
problem = GeometricProblem(dimension=3, use_prototype=False) # no prototype based selection
|
||||||
|
|
||||||
|
problem.add_point('v1', vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v2', vector([1.0, 0.0, 0.0]))
|
||||||
|
problem.add_point('v3', vector([0.0, 1.0, 0.0]))
|
||||||
|
problem.add_point('v4', vector([0.5, 0.5, 1.0]))
|
||||||
|
problem.add_point('v5', vector([0.5, 0.5,-1.0]))
|
||||||
|
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v2', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v3', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v4', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v1', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v2', 'v5', 10.0))
|
||||||
|
problem.add_constraint(DistanceConstraint('v3', 'v5', 10.0))
|
||||||
|
|
||||||
|
#problem.add_constraint(SelectionConstraint(is_right_handed, ['v1','v2','v4','v5']))
|
||||||
|
problem.add_constraint(RightHandedConstraint('v1','v2','v4','v5'))
|
||||||
|
|
||||||
|
return problem
|
||||||
|
|
||||||
|
|
||||||
|
def test3d():
|
||||||
|
#diag_select("clsolver")
|
||||||
|
test(double_tetrahedron_problem())
|
||||||
|
test(ada_tetrahedron_problem())
|
||||||
|
test(double_banana_problem())
|
||||||
|
test(double_banana_plus_one_problem())
|
||||||
|
test(random_triangular_problem_3D(10,10.0,0.0,0.5))
|
||||||
|
test(random_distance_problem_3D(10,1.0,0.0))
|
||||||
|
test(fix1_problem_3d())
|
||||||
|
test(fix2_problem_3d())
|
||||||
|
test(fix3_problem_3d())
|
||||||
|
test(selection_problem())
|
||||||
|
selection_test()
|
||||||
|
test(overconstrained_tetra())
|
||||||
|
test(diamond_3d())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test3d()
|
40
test/test_generic.py
Normal file
40
test/test_generic.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""This module provides some generic tests routines for the GeoSolver.
|
||||||
|
These can be used by other specific test modules, i.e. 2d, 3d, etc.
|
||||||
|
The tests are also simple examples of how to use of the GeomSolver API"""
|
||||||
|
|
||||||
|
from geosolver.geometric import GeometricProblem, GeometricSolver
|
||||||
|
from geosolver.vector import vector
|
||||||
|
from geosolver.diagnostic import diag_select, diag_print
|
||||||
|
import geosolver.tolerance as tolerance
|
||||||
|
|
||||||
|
# ------- generic test -------
|
||||||
|
|
||||||
|
def test(problem):
|
||||||
|
"""Test solver on a given problem"""
|
||||||
|
#diag_select(".*")
|
||||||
|
print "problem:"
|
||||||
|
print problem
|
||||||
|
print "Solving..."
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
print "...done"
|
||||||
|
print "drplan:"
|
||||||
|
print solver.dr
|
||||||
|
print "top-level rigids:",list(solver.dr.top_level())
|
||||||
|
result = solver.get_result()
|
||||||
|
print "result:"
|
||||||
|
print result
|
||||||
|
print "result is",result.flag, "with", len(result.solutions),"solutions"
|
||||||
|
check = True
|
||||||
|
if len(result.solutions) == 0:
|
||||||
|
check = False
|
||||||
|
diag_select("(GeometricProblem.verify)|(satisfied)")
|
||||||
|
for sol in result.solutions:
|
||||||
|
print "solution:",sol
|
||||||
|
check = check and problem.verify(sol)
|
||||||
|
if check:
|
||||||
|
print "all solutions valid"
|
||||||
|
else:
|
||||||
|
print "INVALID"
|
||||||
|
|
||||||
|
|
25
test/test_geometry.py
Normal file
25
test/test_geometry.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""This module provides some tests for the GeoSolver.
|
||||||
|
These tests are concerned with geometric primitives.
|
||||||
|
The tests are also simple examples of how to use of the GeomSolver API"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
from test_generic import test
|
||||||
|
from geosolver.geometric import GeometricProblem, GeometricSolver, DistanceConstraint, AngleConstraint, FixConstraint
|
||||||
|
from geosolver.geometric import Point, Line, CoincidenceConstraint
|
||||||
|
from geosolver.vector import vector
|
||||||
|
from geosolver.diagnostic import diag_select, diag_print
|
||||||
|
|
||||||
|
def line_problem():
|
||||||
|
"""A problem with a Point, a Line and a CoincicentConstraint"""
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
problem.add_variable(Point('p1'),vector([0.0, 0.0, 0.0]))
|
||||||
|
problem.add_variable(Line('l1'),vector([0.0, 0.0, 0.0, 1.0, 1.0, 1.0]))
|
||||||
|
problem.add_constraint(CoincidenceConstraint(Point('p1'), Line('l1')))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def test_line():
|
||||||
|
test(line_problem())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_line()
|
146
test/test_mate.py
Normal file
146
test/test_mate.py
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""This module provides an example of how to use GeoSolver to define 3D blocks
|
||||||
|
and how to mate them using the Mate constraint."""
|
||||||
|
|
||||||
|
import random
|
||||||
|
import math
|
||||||
|
from geosolver.graph import Graph
|
||||||
|
from test_generic import test
|
||||||
|
from geosolver.intersections import translate_3D, rotate_3D_x, rotate_3D_y, rotate_3D_z,scale_3D, id_transform_3D
|
||||||
|
from geosolver.geometric import MateConstraint, RigidConstraint
|
||||||
|
from geosolver.geometric import GeometricProblem, GeometricSolver
|
||||||
|
from geosolver.geometric import DistanceConstraint,AngleConstraint, FixConstraint,RightHandedConstraint
|
||||||
|
from geosolver.vector import vector
|
||||||
|
from geosolver.randomproblem import random_triangular_problem_3D, random_distance_problem_3D
|
||||||
|
from geosolver.diagnostic import diag_select, diag_print
|
||||||
|
from geosolver.intersections import distance_2p, angle_3p
|
||||||
|
from geosolver.configuration import Configuration
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
|
||||||
|
# ------------- creating and manupulating blocks ---------
|
||||||
|
|
||||||
|
def block_var(block, index):
|
||||||
|
return str(block)+"#"+str(index)
|
||||||
|
|
||||||
|
def add_block(problem,name,x,y,z):
|
||||||
|
"""A block with variables name+#1...8 and dimensions x,y,z"""
|
||||||
|
problem.add_point(block_var(name,'left-bot-front'), vector([-1.0, -1.0, -1.0]))
|
||||||
|
problem.add_point(block_var(name,'left-bot-back'), vector([-1.0, -1.0, 1.0]))
|
||||||
|
problem.add_point(block_var(name,'left-top-front'), vector([-1.0, 1.0, -1.0]))
|
||||||
|
problem.add_point(block_var(name,'left-top-back'), vector([-1.0, 1.0, 1.0]))
|
||||||
|
problem.add_point(block_var(name,'right-bot-front'), vector([1.0, -1.0, -1.0]))
|
||||||
|
problem.add_point(block_var(name,'right-bot-back'), vector([1.0, -1.0, 0.0]))
|
||||||
|
problem.add_point(block_var(name,'right-top-front'), vector([1.0, 1.0, -1.0]))
|
||||||
|
problem.add_point(block_var(name,'right-top-back'), vector([1.0, 1.0, 1.0]))
|
||||||
|
conf = Configuration({
|
||||||
|
block_var(name,'left-bot-front'):vector([-x/2, -y/2, -z/2]),
|
||||||
|
block_var(name,'left-bot-back'):vector([-x/2, -y/2, +z/2]),
|
||||||
|
block_var(name,'left-top-front'):vector([-x/2, +y/2, -z/2]),
|
||||||
|
block_var(name,'left-top-back'):vector([-x/2, +y/2, +z/2]),
|
||||||
|
block_var(name,'right-bot-front'):vector([+x/2, -y/2, -z/2]),
|
||||||
|
block_var(name,'right-bot-back'):vector([+x/2, -y/2, +z/2]),
|
||||||
|
block_var(name,'right-top-front'):vector([+x/2, +y/2, -z/2]),
|
||||||
|
block_var(name,'right-top-back'):vector([+x/2, +y/2, +z/2])
|
||||||
|
})
|
||||||
|
problem.add_constraint(RigidConstraint(conf))
|
||||||
|
return problem
|
||||||
|
|
||||||
|
def mate_blocks(problem, block1, o1, x1, y1, block2, o2, x2, y2, dx, dy):
|
||||||
|
"""Mate two blocks.
|
||||||
|
block1 and block2 are the names of the blocks.
|
||||||
|
o1, x1 and x2 are vertices of the blocks.
|
||||||
|
o1-x1 identifies the so-called x-edge in block1.
|
||||||
|
o1-y1 identifies the y-edge in block1.
|
||||||
|
--- no longer needed -- The x-edge and y-edge must be actual egdes in block1, or an error will be generated.
|
||||||
|
The same for block2.
|
||||||
|
dx is the relative position of the x-edges of the two blocks.
|
||||||
|
dy is the relative position of the y-edges of the two blocks.
|
||||||
|
Note that if the blocks are not actually block-shaped, the axis will not be properly
|
||||||
|
aligned and the faces will not be properly mated.
|
||||||
|
"""
|
||||||
|
# determine variable names of the points
|
||||||
|
vo1 = block_var(block1,o1)
|
||||||
|
vx1 = block_var(block1,x1)
|
||||||
|
vy1 = block_var(block1,y1)
|
||||||
|
vo2 = block_var(block2,o2)
|
||||||
|
vx2 = block_var(block2,x2)
|
||||||
|
vy2 = block_var(block2,y2)
|
||||||
|
# ---- no longer needed --- determine points opposite to given origin and plane
|
||||||
|
# vz1 = block_var(block1,get_block_opposite(o1, x1, y1))
|
||||||
|
# vz2 = block_var(block2,get_block_opposite(o2, x2, y2))
|
||||||
|
# determine transformation
|
||||||
|
trans = translate_3D(dx, dy,0.0)
|
||||||
|
# add constraint
|
||||||
|
problem.add_constraint(MateConstraint(vo1,vx1,vy1,vo2,vx2,vy2,trans))
|
||||||
|
|
||||||
|
|
||||||
|
# ----- no longer used, but maybe in the future? -- ----
|
||||||
|
|
||||||
|
# create a graph of the edges in a block
|
||||||
|
blockgraph = Graph()
|
||||||
|
edges = [('left-bot-front','left-bot-back'),
|
||||||
|
('left-bot-front','left-top-front'),
|
||||||
|
('left-bot-front','right-bot-front'),
|
||||||
|
('left-bot-back','left-top-back'),
|
||||||
|
('left-bot-back','right-bot-back'),
|
||||||
|
('left-top-front','left-top-back'),
|
||||||
|
('left-top-front','right-top-front'),
|
||||||
|
('left-top-back','right-top-back'),
|
||||||
|
('right-bot-front','right-bot-back'),
|
||||||
|
('right-bot-front','right-top-front'),
|
||||||
|
('right-bot-back','right-top-back'),
|
||||||
|
('right-top-font','right-top-back')]
|
||||||
|
|
||||||
|
for edge in edges:
|
||||||
|
# add bi-directional edge to graoh
|
||||||
|
blockgraph.add_bi(edge[0], edge[1])
|
||||||
|
|
||||||
|
def get_block_opposite(o, x, y):
|
||||||
|
"""return the index of the vertex connected to o but not connected to x and y"""
|
||||||
|
if not blockgraph.has_vertex(o):
|
||||||
|
raise Exception, "vertex %s is not a block vertex"%(str(o))
|
||||||
|
# determine vertices connected to
|
||||||
|
connected = list(blockgraph.outgoing_vertices(o))
|
||||||
|
if x not in connected:
|
||||||
|
raise Exception, "edge (%s,%s) is not a block edge"%(str(o),str(x))
|
||||||
|
if y not in connected:
|
||||||
|
raise Exception, "edge (%s,%s) is not a block edge"%(str(o),str(y))
|
||||||
|
connected.remove(x)
|
||||||
|
connected.remove(y)
|
||||||
|
if len(connected) != 1:
|
||||||
|
raise Exception, "could not find opposite edge, because I am an idiot."
|
||||||
|
return connected[0]
|
||||||
|
|
||||||
|
# ----------- test mate constraint
|
||||||
|
|
||||||
|
def test_mate():
|
||||||
|
problem = GeometricProblem(dimension=3)
|
||||||
|
|
||||||
|
# create and mate two blocks
|
||||||
|
add_block(problem, "A", 4.0, 2.0, 6.0)
|
||||||
|
add_block(problem, "B", 4.0, 2.0, 6.0)
|
||||||
|
mate_blocks(problem, "A", 'right-bot-front','right-bot-back','right-top-front',
|
||||||
|
"B", 'left-bot-front','left-bot-back','left-top-front',
|
||||||
|
0.5, 0.0)
|
||||||
|
# add global coordinate system
|
||||||
|
problem.add_point("origin",vector([0.0,0.0,0.0]))
|
||||||
|
problem.add_point("x-axis",vector([1.0,0.0,0.0]))
|
||||||
|
problem.add_point("y-axis",vector([0.0,1.0,0.0]))
|
||||||
|
problem.add_constraint(FixConstraint("origin",vector([0.0,0.0,0.0])))
|
||||||
|
problem.add_constraint(FixConstraint("x-axis",vector([1.0,0.0,0.0])))
|
||||||
|
problem.add_constraint(FixConstraint("y-axis",vector([0.0,1.0,0.0])))
|
||||||
|
|
||||||
|
# fix block1 to cs
|
||||||
|
problem.add_constraint(MateConstraint("origin","x-axis","y-axis",
|
||||||
|
block_var("A", "left-bot-front"),block_var("A", "right-bot-front"),block_var("A", "left-top-front"),
|
||||||
|
id_transform_3D()))
|
||||||
|
|
||||||
|
test(problem)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
#test_twoblocks()
|
||||||
|
#test_z_index()
|
||||||
|
test_mate()
|
||||||
|
|
91
test/test_performance.py
Normal file
91
test/test_performance.py
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""This module provides some tests for the GeoSolver.
|
||||||
|
These test are concerned with the performance of the solver
|
||||||
|
The tests are also simple examples of how to use of the GeomSolver API"""
|
||||||
|
|
||||||
|
import random
|
||||||
|
import math
|
||||||
|
from test_generic import test
|
||||||
|
from geosolver.geometric import GeometricProblem, GeometricSolver, DistanceConstraint,AngleConstraint, FixConstraint,RightHandedConstraint
|
||||||
|
from geosolver.vector import vector
|
||||||
|
from geosolver.randomproblem import random_triangular_problem_3D, random_distance_problem_3D
|
||||||
|
from geosolver.diagnostic import diag_select, diag_print
|
||||||
|
from geosolver.intersections import distance_2p, angle_3p
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
# create statistics for solving time
|
||||||
|
def stats_solving():
|
||||||
|
print "size \t # \t time \t result"
|
||||||
|
for size in range(4,31):
|
||||||
|
for i in range(1,10):
|
||||||
|
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
||||||
|
t1 = time()
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
result = solver.get_status()
|
||||||
|
t2 = time()
|
||||||
|
t = t2-t1
|
||||||
|
print size,"\t",i,"\t",t,"\t",result
|
||||||
|
|
||||||
|
# create statistics for incremental solving time
|
||||||
|
def stats_incremental():
|
||||||
|
#diag_select("clsolver.remove")
|
||||||
|
print "size \t # \t time \t result"
|
||||||
|
for size in range(4,31):
|
||||||
|
for i in range(1,10):
|
||||||
|
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
t1 = time()
|
||||||
|
constraint = random.choice(problem.cg.constraints())
|
||||||
|
problem.rem_constraint(constraint)
|
||||||
|
problem.add_constraint(constraint)
|
||||||
|
result = solver.get_status()
|
||||||
|
t2 = time()
|
||||||
|
t = t2-t1
|
||||||
|
print size,"\t",i,"\t",t,"\t",result
|
||||||
|
|
||||||
|
# create statistics for parametric change
|
||||||
|
def stats_parametric_incremental():
|
||||||
|
#diag_select("clsolver.remove")
|
||||||
|
print "size \t # \t time \t result"
|
||||||
|
for size in range(4,31):
|
||||||
|
for i in range(1,10):
|
||||||
|
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
constraint = random.choice(problem.cg.constraints())
|
||||||
|
#problem.rem_constraint(constraint)
|
||||||
|
#problem.add_constraint(constraint)
|
||||||
|
#problem.rem_constraint(constraint)
|
||||||
|
#problem.add_constraint(constraint)
|
||||||
|
t1 = time()
|
||||||
|
#problem.rem_constraint(constraint)
|
||||||
|
#problem.add_constraint(constraint)
|
||||||
|
#constraint.set_parameter(constraint.get_parameter())
|
||||||
|
result = solver.get_status()
|
||||||
|
t2 = time()
|
||||||
|
t = t2-t1
|
||||||
|
print size,"\t",i,"\t",t,"\t",result
|
||||||
|
|
||||||
|
# create statistics for parametric change
|
||||||
|
def stats_parametric():
|
||||||
|
#diag_select("clsolver.remove")
|
||||||
|
print "size \t # \t time \t result"
|
||||||
|
for size in range(4,31):
|
||||||
|
for i in range(1,10):
|
||||||
|
problem = random_triangular_problem_3D(size,10.0,0.0,0.0)
|
||||||
|
solver = GeometricSolver(problem)
|
||||||
|
constraint = random.choice(problem.cg.constraints())
|
||||||
|
t1 = time()
|
||||||
|
constraint.set_parameter(constraint.get_parameter())
|
||||||
|
result = solver.get_status()
|
||||||
|
t2 = time()
|
||||||
|
t = t2-t1
|
||||||
|
print size,"\t",i,"\t",t,"\t",result
|
||||||
|
|
||||||
|
def runstats():
|
||||||
|
stats_solving()
|
||||||
|
stats_incremental()
|
||||||
|
stats_parametric_incremental()
|
||||||
|
stats_parametric()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
runstats()
|
Loading…
Reference in New Issue
Block a user