Example #1
0
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
Example #2
0
    def solve_shape(self, layers):
        for layer in layers:
            print("Solving shape ", layer.id)

            pt0 = layer.named_pairs[0][0]
            pt1 = layer.named_pairs[1][0]
            pt2 = layer.named_pairs[2][0]
            for i, point in enumerate(layer.named_pairs):
                # Add initial points
                self.problem.add_variable(point[0],
                                          vector([point[1], point[2], 0]))

                # Lock them together
                if i > 0:
                    self.problem.add_constraint(
                        DistanceConstraint(
                            pt0, point[0],
                            distance_2p(self.problem.get_point(pt0),
                                        self.problem.get_point(point[0]))))
                if i > 1:
                    self.problem.add_constraint(
                        AngleConstraint(
                            pt0, pt1, point[0],
                            angle_3p(self.problem.get_point(pt0),
                                     self.problem.get_point(pt1),
                                     self.problem.get_point(point[0]))))
                if i > 2:
                    self.problem.add_constraint(
                        AngleConstraint(
                            pt0, pt2, point[0],
                            angle_3p(self.problem.get_point(pt0),
                                     self.problem.get_point(pt2),
                                     self.problem.get_point(point[0]))))
Example #3
0
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
Example #4
0
def add_random_constraint(problem, ratio):
    """add a random constraint to a problem, with a given ratio angles/distances"""
    if random.random() < ratio:
        # add angle
        pointvars = list(problem.cg.variables())
        random.shuffle(pointvars)
        v1 = pointvars[0]
        v2 = pointvars[1]
        v3 = pointvars[2]
        p1 = problem.get_point(v1)
        p2 = problem.get_point(v2)
        p3 = problem.get_point(v3)
        angle = angle_3p(p1, p2, p3)
        con = AngleConstraint(v1, v2, v3, angle)
        diag_print("**Add constraint:" + str(con), "drplan")
        problem.add_constraint(con)
    else:
        # add distance
        pointvars = list(problem.cg.variables())
        random.shuffle(pointvars)
        v1 = pointvars[0]
        v2 = pointvars[1]
        p1 = problem.get_point(v1)
        p2 = problem.get_point(v2)
        dist = distance_2p(p1, p2)
        con = DistanceConstraint(v1, v2, dist)
        diag_print("**Add constraint:" + str(con), "drplan")
        problem.add_constraint(con)
    return
Example #5
0
def random_triangular_problem_3D(npoints, radius, roundoff, pangle):
    problem = random_distance_problem_3D(npoints, radius, roundoff)
    points = list(problem.cg.variables())
    triangles = []
    for i1 in range(len(points)):
        for i2 in range(i1 + 1, len(points)):
            for i3 in range(i2 + 1, len(points)):
                p1 = points[i1]
                p2 = points[i2]
                p3 = points[i3]
                if (problem.get_distance(p1, p2)
                        and problem.get_distance(p1, p3)
                        and problem.get_distance(p2, p3)):
                    triangles.append((p1, p2, p3))
    for tri in triangles:
        for i in range(2):
            p = tri[i]
            pl = tri[(i + 1) % 3]
            pr = tri[(i + 2) % 3]
            if problem.get_distance(pl, pr) and random.random() < pangle:
                problem.rem_constraint(problem.get_distance(pl, pr))
                angle = angle_3p(problem.get_point(pl), problem.get_point(p),
                                 problem.get_point(pr))
                problem.add_constraint(AngleConstraint(pl, p, pr, angle))
    return problem
Example #6
0
def randomize_hedgehogs(problem):
    """combine adjacent angles to hedgehogs and replace with different angles.
       modifies problem
    """
    assert problem.dimension == 2
    angles = filter(lambda c: isinstance(c, AngleConstraint),
                    problem.cg.constraints())
    hogs = set()
    # make hogs from angles
    for angle in angles:
        vars = angle.variables()
        hog = (vars[1], frozenset([vars[0], vars[2]]))
        hogs.add(hog)
        # REMOVE CONSTRAINT
        problem.rem_constraint(angle)

    # combine hogs
    queue = list(hogs)
    while len(queue) > 0:
        hog1 = queue.pop()
        if hog1 not in hogs:
            continue
        cvar1 = hog1[0]
        xvars1 = hog1[1]
        for hog2 in hogs:
            if hog1 == hog2:
                continue
            cvar2 = hog2[0]
            xvars2 = hog2[1]
            if cvar1 == cvar2:
                shared = xvars1.intersection(xvars2)
                if len(shared) > 0:
                    hogs.remove(hog1)
                    hogs.remove(hog2)
                    newhog = (cvar1, xvars1.union(xvars2))
                    hogs.add(newhog)
                    queue.append(newhog)
                    break

    # rewrite hogs
    for hog in hogs:
        cvar = hog[0]
        xvars = hog[1]
        varlist = list(xvars)
        random.shuffle(varlist)
        for i in range(1, len(varlist)):
            v1 = varlist[i - 1]
            v2 = cvar
            v3 = varlist[i]
            # ADD CONSTRAINT
            problem.add_constraint(
                AngleConstraint(
                    v1, v2, v3,
                    angle_3p(problem.get_point(v1), problem.get_point(v2),
                             problem.get_point(v3))))

    return problem
Example #7
0
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
Example #8
0
 def satisfied(self, mapping):
     """return True iff mapping from variable names to points
     satisfies constraint"""
     a = mapping[self._variables[0]]
     b = mapping[self._variables[1]]
     c = mapping[self._variables[2]]
     ang = angle_3p(a, b, c)
     if ang is None:
         result = False
         cmp = self._value
     else:
         if len(a) >= 3:
             cmp = abs(self._value)
         else:
             cmp = self._value
         result = tol_eq(ang, cmp)
     if result is False:
         diag_print(
             "measured angle = " + str(ang) + ",parameter value = " +
             str(cmp), "geometric")
     return result
Example #9
0
def randomize_balloons(problem):
    """combine adjacent angles to balloons and replace with different angles.
       modifies problem
    """
    assert problem.dimension == 2
    angles = filter(lambda c: isinstance(c, AngleConstraint),
                    problem.cg.constraints())
    balloons = set()
    toremove = set()
    # make hogs from angles
    for angle1 in angles:
        cvar1 = angle1.variables()[1]
        for angle2 in angles:
            if angle2 == angle1: continue
            cvar2 = angle2.variables()[1]
            if cvar1 == cvar2: continue
            shared = set(angle1.variables()).intersection(angle2.variables())
            if len(shared) == 3:
                balloon = frozenset(angle1.variables())
                balloons.add(balloon)
                toremove.add(angle1)
                toremove.add(angle2)

    # remove constraints
    for con in toremove:
        problem.rem_constraint(con)

    print("initial balloons", balloons)

    # combine balloons
    queue = list(balloons)
    while len(queue) > 0:
        bal1 = queue.pop()
        if bal1 not in balloons:
            continue
        for bal2 in balloons:
            if bal1 == bal2:
                continue
            shared = bal1.intersection(bal2)
            if len(shared) >= 2:
                balloons.remove(bal1)
                balloons.remove(bal2)
                newbal = (bal1.union(bal2))
                balloons.add(newbal)
                queue.append(newbal)
                break

    print("combined balloons", balloons)

    # rewrite balloons
    for bal in balloons:
        # constrain first three points
        vars = list(bal)
        random.shuffle(vars)
        for i in range(2, len(vars)):
            lvars = vars[i - 2:i + 1]
            random.shuffle(lvars)
            problem.add_constraint(
                AngleConstraint(
                    lvars[0], lvars[1], lvars[2],
                    angle_3p(problem.get_point(lvars[0]),
                             problem.get_point(lvars[1]),
                             problem.get_point(lvars[2]))))
            problem.add_constraint(
                AngleConstraint(
                    lvars[1], lvars[2], lvars[0],
                    angle_3p(problem.get_point(lvars[1]),
                             problem.get_point(lvars[2]),
                             problem.get_point(lvars[0]))))

    return problem
Example #10
0
def _constraint_group(problem, group, dependend, angleratio):
    """Add constraints to problem to constrain given group of points. 
       Group may be optionally dependend on pair of points.
       Creates angle constraints with a given chance."""

    diag_print(
        "_constraint_group(group=" + str(group.keys()) + ",dep=" +
        str(dependend) + ")", "geometric._constraint_group")
    if len(group) == 2:
        if dependend == None:
            v1 = group.keys()[0]
            v2 = group.keys()[1]
            p1 = group[v1]
            p2 = group[v2]
            dist = distance_2p(p1, p2)
            con = DistanceConstraint(v1, v2, dist)
            diag_print("**Add constraint:" + str(con),
                       "geometric._constraint_group")
            problem.add_constraint(con)
    elif len(group) >= 3:
        # pick three points
        keys = group.keys()
        if dependend == None:
            v1 = random.choice(keys)
        else:
            v1 = dependend[0]
        keys.remove(v1)
        if dependend == None:
            v2 = random.choice(keys)
        else:
            v2 = dependend[1]
        keys.remove(v2)
        v3 = random.choice(keys)
        keys.remove(v3)
        # create three groups
        g = [{}, {}, {}]
        g[0][v1] = group[v1]
        g[0][v2] = group[v2]
        g[1][v1] = group[v1]
        g[1][v3] = group[v3]
        g[2][v2] = group[v2]
        g[2][v3] = group[v3]
        # distribute remaining points over groups
        while (len(keys) > 0):
            k = keys.pop()
            if dependend == None:
                i = random.randint(0, 2)
            else:
                i = random.randint(1, 2)
            g[i][k] = group[k]
        # compute facts from prototype
        p1 = group[v1]
        p2 = group[v2]
        p3 = group[v3]
        # group 0: if independend, add at least one independent group
        if dependend == None:
            _constraint_group(problem, g[0], None, angleratio)
        # group 1: random: angle constraint or independend group
        if random.random() > angleratio:
            _constraint_group(problem, g[1], None, angleratio)
        else:
            angle = angle_3p(p1, p2, p3)
            con = AngleConstraint(v1, v2, v3, angle)
            diag_print("**Add constraint:" + str(con),
                       "geometric._constraint_group")
            problem.add_constraint(con)
            _constraint_group(problem, g[1], [v1, v3], angleratio)
        # group 2: random: angle constraint, two configuratins, or independend group
        if random.random() > angleratio:
            _constraint_group(problem, g[2], None, angleratio)
        elif random.random() < 0.5:
            angle = angle_3p(p2, p1, p3)
            con = AngleConstraint(v2, v1, v3, angle)
            diag_print("**Add constraint:" + str(con),
                       "geometric._constraint_group")
            problem.add_constraint(con)
            _constraint_group(problem, g[2], [v2, v3], angleratio)
        else:
            angle = angle_3p(p2, p3, p1)
            con = AngleConstraint(v2, v3, v1, angle)
            diag_print("**Add constraint:" + str(con),
                       "geometric._constraint_group")
            problem.add_constraint(con)
            _constraint_group(problem, g[2], [v2, v3], angleratio)