re-organised test suite

This commit is contained in:
kwikrick 2012-08-23 20:01:49 +00:00
parent f60475eb3d
commit dc5b1c708b
9 changed files with 1178 additions and 997 deletions

View File

@ -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)"""

View File

@ -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()

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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()