re-organised test suite
This commit is contained in:
parent
f60475eb3d
commit
dc5b1c708b
|
@ -190,10 +190,6 @@ class GeometricProblem (Notifier, Listener):
|
|||
else:
|
||||
return None
|
||||
|
||||
def get_rigid(self, vars):
|
||||
print "GeometricProblem.get_rigid NOT IMPLEMENTED"
|
||||
return None
|
||||
|
||||
def get_fix(self, p):
|
||||
"""return the fix constraint on given point, or None"""
|
||||
on_p = self.cg.get_constraints_on(p)
|
||||
|
@ -209,6 +205,15 @@ class GeometricProblem (Notifier, Listener):
|
|||
print "GeometricProblem.get_coincidence NOT IMPLEMENTED"
|
||||
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):
|
||||
"""returns true iff all constraints satisfied by given solution.
|
||||
solution is a dictionary mapping variables (names) to values (points)"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# ----------- random problem generation ----------------
|
||||
#----------- random problem generation ----------------
|
||||
|
||||
import random
|
||||
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))
|
||||
return problem
|
||||
|
||||
|
||||
def test():
|
||||
#problem = random_triangular_problem_3D(10, 10.0, 0.0, 0.5)
|
||||
problem = random_problem_2D(10, 10.0, 0.0, 0.6)
|
||||
problem = randomize_angles(problem)
|
||||
print problem
|
||||
|
||||
if __name__ == "__main__": test()
|
||||
#problem = random_triangular_problem_3D(10, 10.0, 0.0, 0.5)
|
||||
problem = random_problem_2D(10, 10.0, 0.0, 0.6)
|
||||
problem = randomize_angles(problem)
|
||||
print problem
|
||||
|
||||
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