line mapping (work in progress)

This commit is contained in:
kwikrick 2012-10-05 12:07:50 +00:00
parent 193b224850
commit eda5689f0a
3 changed files with 72 additions and 9 deletions

View File

@ -13,6 +13,10 @@ Speed: The solver is currently much too slow. The problem is the pattern
- compliled implementation (Psycho/C++/Haskell/???) - compliled implementation (Psycho/C++/Haskell/???)
Rules: More rewrite rules to increase the problem domain: Rules: More rewrite rules to increase the problem domain:
- need 2d and 3d rules for merging radial clusters
2D:H+H->H sharing center and 1 point
3D:H+H+H-> sharing center and 3 points, 2 points per pair of hogs
3D:H+H->H sharing center and 2 points (local overconstrained)
- need 3d rule: merge of 2 rigids with 2 shared points (hinge) + hog with angle not on hinge points - need 3d rule: merge of 2 rigids with 2 shared points (hinge) + hog with angle not on hinge points
- larger subproblems (octahedron, variable radius spheres/cylinders) - larger subproblems (octahedron, variable radius spheres/cylinders)
- new clusters types (N degrees of freedom) - new clusters types (N degrees of freedom)
@ -27,6 +31,8 @@ Extentions:
BUGS: BUGS:
- prototype based selection doesn't seem to work on line mappings
- stop problem from rotating and jumping around when there are no fixed points. It should - stop problem from rotating and jumping around when there are no fixed points. It should
be as close to the prototype as possible; be as close to the prototype as possible;
should have at least have one (2d) or two(3d) edge(s) with the same offset and orientation. should have at least have one (2d) or two(3d) edge(s) with the same offset and orientation.
@ -59,3 +65,13 @@ def diamond_3d():
FixConstraint(v2=[-5.0, 5.0, 0.0]) not satisfied FixConstraint(v2=[-5.0, 5.0, 0.0]) not satisfied
FixConstraint(v1=[0.0, 0.0, 0.0]) not satisfied FixConstraint(v1=[0.0, 0.0, 0.0]) not satisfied
- 2D deriveADD accepts this pattern, but fails during execution.
Angle(p3,p2,p4)
Rigid(p1,p2,p4)
Distance(p1,p3)
Note: this pattern can be solved only in 2D. To keep DeriveADD general
(and simple), pattern matching should be more strict, allowing only
patterns where the angle constraint is in the derived triangle.
An extra rule is needed to merge two angles (radial clusters) in 2D.
In 3D, three radial clusters can be merged.

View File

@ -621,7 +621,16 @@ class GeometricSolver (Listener):
# add add-hoc attributes to rigid, so we can distinguish vertex and normal! # add add-hoc attributes to rigid, so we can distinguish vertex and normal!
dist.vertex = v dist.vertex = v
dist.normal = n dist.normal = n
# add to mapping # add rigids for created points, needed for prototypes
# NOTE: adding non-problem variables to mapping!
# TODO: clean up after removal of line
vertex_rigid = Rigid([dist.vertex])
self.dr.add(vertex_rigid)
self._map[dist.vertex] = vertex_rigid
normal_rigid = Rigid([dist.normal])
self.dr.add(normal_rigid)
self._map[dist.normal] = normal_rigid
# add line to mapping
self._map[line] = dist self._map[line] = dist
self._map[dist] = line self._map[dist] = line
self.dr.add(dist) self.dr.add(dist)
@ -637,6 +646,12 @@ class GeometricSolver (Listener):
# add add-hoc attributes to rigid, so we can distinguish vertex and normal! # add add-hoc attributes to rigid, so we can distinguish vertex and normal!
dist.vertex = v dist.vertex = v
dist.normal = n dist.normal = n
# add rigids for created points, needed for prototypes
# NOTE: adding non-problem variables to mapping!
# TODO: clean up after removal of line
normal_rigid = Rigid([dist.normal])
self.dr.add(normal_rigid)
self._map[dist.normal] = normal_rigid
# add to mapping # add to mapping
self._map[line] = dist self._map[line] = dist
self._map[dist] = line self._map[dist] = line
@ -878,21 +893,37 @@ class GeometricSolver (Listener):
self.dr.set(cluster, [conf]) self.dr.set(cluster, [conf])
def _update_line(self, variable): def _update_line(self, variable):
if self.dimension == 2:
cluster = self._map[variable] cluster = self._map[variable]
proto = self.problem.get_prototype(variable) proto = self.problem.get_prototype(variable)
line_vertex = cluster.vertex line_vertex = cluster.vertex
line_normal = cluster.normal line_normal = cluster.normal
if self.dimension == 2:
# determine vertex and normal prototype coordinates
p1 = proto[0:2] p1 = proto[0:2]
p2 = proto[2:4] p2 = proto[2:4]
v = p1 v = p1
n = perp_2d(p2-p1) n = perp_2d(p2-p1)
# update prototypes of created point variables
if line_vertex in self._map:
vertex_rigid = self._map[line_vertex]
conf = Configuration({line_vertex: v})
self.dr.set(vertex_rigid, [conf])
diag_print("set "+str(vertex_rigid)+" to "+str(conf),"GeometricSolver")
if line_normal in self._map:
normal_rigid = self._map[line_normal]
conf = Configuration({line_normal: n})
self.dr.set(normal_rigid, [conf])
diag_print("set "+str(normal_rigid)+" to "+str(conf),"GeometricSolver")
# update line configuration
conf = Configuration({line_vertex:v, line_normal:n}) conf = Configuration({line_vertex:v, line_normal:n})
self.dr.set(cluster, [conf]) self.dr.set(cluster, [conf])
diag_print("set "+str(cluster)+" to "+str(conf),"GeometricSolver") diag_print("set "+str(cluster)+" to "+str(conf),"GeometricSolver")
elif self.dimension == 3: elif self.dimension == 3:
raise NotImplementedError raise NotImplementedError
def _update_fix(self): def _update_fix(self):
if self.fixcluster: if self.fixcluster:
vars = self.fixcluster.vars vars = self.fixcluster.vars

View File

@ -99,7 +99,21 @@ def line_problem_2d_2():
problem.add_constraint(DistanceConstraint(Point('p1'), Point('p2'), 5.0)) problem.add_constraint(DistanceConstraint(Point('p1'), Point('p2'), 5.0))
return problem return problem
def line_problem_2d_3(): def line_problem_2d_3a():
"""A problem with a Line and a 3 CoincicentConstraints"""
problem = GeometricProblem(dimension=2)
problem.add_variable(Point('p1'),vector([3.0, 2.0]))
problem.add_variable(Point('p2'),vector([1.0, 1.0]))
problem.add_variable(Line('l1'),vector([0.0, 0.0, 1.0, 1.0]))
problem.add_constraint(CoincidenceConstraint(Point('p1'), Line('l1')))
problem.add_constraint(CoincidenceConstraint(Point('p2'), Line('l1')))
problem.add_constraint(DistanceConstraint(Point('p1'), Point('p2'), 5.0))
problem.add_variable(Point('p3'),vector([1.0, 0.0]))
problem.add_constraint(CoincidenceConstraint(Point('p3'), Line('l1')))
problem.add_constraint(DistanceConstraint(Point('p3'), Point('p2'), 8.0))
return problem
def line_problem_2d_3b():
"""A problem with a Line and a 3 CoincicentConstraints""" """A problem with a Line and a 3 CoincicentConstraints"""
problem = GeometricProblem(dimension=2) problem = GeometricProblem(dimension=2)
problem.add_variable(Point('p1'),vector([3.0, 2.0])) problem.add_variable(Point('p1'),vector([3.0, 2.0]))
@ -113,6 +127,7 @@ def line_problem_2d_3():
problem.add_constraint(DistanceConstraint(Point('p1'), Point('p3'), 8.0)) problem.add_constraint(DistanceConstraint(Point('p1'), Point('p3'), 8.0))
return problem return problem
def line_problem_2d_4(): def line_problem_2d_4():
"""A problem with a Line and a 4 CoincicentConstraints""" """A problem with a Line and a 4 CoincicentConstraints"""
problem = GeometricProblem(dimension=2) problem = GeometricProblem(dimension=2)
@ -136,7 +151,8 @@ def test_line():
#test(line_problem_2d_0()) #test(line_problem_2d_0())
#test(line_problem_2d_1()) #test(line_problem_2d_1())
#test(line_problem_2d_2()) #test(line_problem_2d_2())
test(line_problem_2d_3()) test(line_problem_2d_3a())
#test(line_problem_2d_3b())
#test(line_problem_2d_4()) #test(line_problem_2d_4())
#test(line_problem_3d_0()) #test(line_problem_3d_0())