Example #1
0
    def define_shape(self, layer):
        i = 0
        x_p = 0
        y_p = 0
        xp_p = 0.0
        yp_p = 0.0

        for p in layer.straight_pairs:
            #path4581_p1_x
            name = layer.name + '_p' + str(i) + '_'
            nameX = name + 'x'
            nameY = name + 'y'
            x = kiwisolver.Variable(nameX)
            y = kiwisolver.Variable(nameY)
            self.variables[nameX] = x
            self.variables[nameY] = y
            xp = p[0]
            yp = p[1]
            if i > 0:
                x_constraint = (x == (x_p + (xp - xp_p)))
                y_constraint = (y == (y_p + (yp - yp_p)))
                self.solver.addConstraint(x_constraint | "strong")
                self.solver.addConstraint(y_constraint | "strong")
            x_p = x
            y_p = y
            xp_p = xp
            yp_p = yp
            i += 1
        return layer
Example #2
0
    def add_joint(self, jname, lname, pname, p):

        #path4581_p1_x
        layername = lname + '_p' + str(pname) + '_'
        layernameX = layername + 'x'
        layernameY = layername + 'y'
        # lx = kiwisolver.Variable(layernameX)
        # ly = kiwisolver.Variable(layernameY)
        lx = self.variables[layernameX]
        ly = self.variables[layernameY]

        jointname = 'joint_' + str(jname) + '_'
        jointnameX = jointname + 'x'
        jointnameY = jointname + 'y'
        if jointnameX not in self.variables.keys():
            jx = kiwisolver.Variable(jointnameX)
            jy = kiwisolver.Variable(jointnameY)
            self.variables[jointnameX] = jx
            self.variables[jointnameY] = jy
        else:
            jx = self.variables[jointnameX]
            jy = self.variables[jointnameY]

        self.solver.addConstraint((lx == jx) | strength_joint)
        self.solver.addConstraint((ly == jy) | strength_joint)
Example #3
0
    def add_fixed(self, layer):
        i = 0

        for p in layer.straight_pairs:
            #path4581_p1_x
            name = layer.name + '_p' + str(i) + '_'
            nameX = name + 'x'
            nameY = name + 'y'
            x = kiwisolver.Variable(nameX)
            y = kiwisolver.Variable(nameY)
            self.solver.addConstraint((x == p[0]) | strength_define)
            self.solver.addConstraint((y == p[1]) | strength_define)
            i += 1
        return layer
Example #4
0
def solve_ordering(nodes):
    """ Solve for the desired order of the list of nodes.

    This function is an implementation detail and should not be
    consumed by code outside of this module.

    Parameters
    ----------
    nodes : list
        The list of PathNode objects which should be ordered. It
        is assumed that all nodes reside in the same group.

    Returns
    -------
    result : list
        The PathNode objects ordered according to the constraints
        specified by the 'before' and 'after' items attributes.

    """
    variables = {}
    for node in nodes:
        variables[node.id] = kiwi.Variable(str(node.id))

    prev_var = None
    constraints = []
    for node in nodes:
        this_var = variables[node.id]
        constraints.append(this_var >= 0)
        if prev_var is not None:  # weakly preserve relative order
            constraints.append((prev_var + 0.1 <= this_var) | 'weak')
        before = node.item.before
        if before:
            if before not in variables:
                msg = "item '%s' has invalid `before` reference '%s'"
                raise ValueError(msg % (node.path, before))
            target_var = variables[before]
            constraints.append((this_var + 0.1 <= target_var) | 'strong')
        after = node.item.after
        if after:
            if after not in variables:
                msg = "item '%s' has invalid `after` reference '%s'"
                raise ValueError(msg % (node.path, after))
            target_var = variables[after]
            constraints.append((target_var + 0.1 <= this_var) | 'strong')
        prev_var = this_var

    solver = kiwi.Solver()
    for cn in constraints:
        solver.addConstraint(cn)
    solver.updateVariables()

    flat = []
    for node in nodes:
        node_var = variables[node.id]
        flat.append((node_var.value(), node))
    flat.sort()

    return [pair[1] for pair in flat]
Example #5
0
    def solve(self):
        joints = self.joints
        layers = self.layers

        for l in layers:
            #Todo: check that shape actually needs constraints before defining
            l = self.define_shape(l)

            #Todo: Finish / test
            if l.fixed == True:
                self.add_fixed(l)

        print(joints)
        for jointlayer in joints:
            print(jointlayer)
            for jp in joints[jointlayer]:
                for l in layers:
                    print(l.name)
                    #print(l)
                    i = 0
                    for p in l.straight_pairs:
                        if (self.encloses(p, jp)):
                            print(jointlayer, l.name, i, p)
                            self.add_joint(jointlayer, l.name, i, p)
                            #joint_assoc[jointlayer].append(l.name)
                        i += 1
        #print(joint_assoc)

        print(self.solver.dumps())
        print(self.solver)
        print(dir(self.solver))
        print(dir(kiwisolver.Variable()))
        print(layers)
        # print(dir(kiwisolver.Expression())) #needs term
        # print(dir(kiwisolver.Term()))   #needs variable
        print(dir(kiwisolver.Term(self.variables['path4518_p3_y'])))

        print(self.variables)
        print(self.variables['path4518_p3_y'])
        print(self.variables['path4518_p3_y'].value())
        print(self.variables['path4518_p3_x'].value())
        print(self.variables['path4520_p1_y'])
        print(self.variables['path4520_p1_y'].value())
        print(self.variables['path4520_p1_x'].value())
        self.solver.updateVariables()
        print(self.variables['path4518_p3_y'])
        print(self.variables['path4518_p3_y'].value())
        print(self.variables['path4518_p3_x'].value())
        print(self.variables['path4520_p1_y'])
        print(self.variables['path4520_p1_y'].value())
        print(self.variables['path4520_p1_x'].value())
        return self.incorporate(self.variables, layers)
Example #6
0
	def __init__(self):
		"""Default constructor.
		"""
		# Margins.
		self.margin_left = 0
		self.margin_right = 0
		self.margin_top = 0
		self.margin_bottom = 0

		# Dimensions of the element. We also have some flags so that we can
		# determine if the dimensions have been properly set yet, and where
		# the dimension information originates.
		self.width = ks.Variable()
		self.height = ks.Variable()
		self.width_constraint = 'none'
		self.height_constraint = 'none'

		# Coordinates of the four edges of the element.
		self.xl = 0.0
		self.xr = 0.0
		self.yt = 0.0
		self.yb = 0.0

		# Layout control information: How does this element lay out its child
		# elements, by row or column? What padding is there between elements?
		self.layout = 'none'
		self.padding = 0.0

		# Label for this element.
		self.label = ''

		# Figure axis.
		self.ax = None

		# Parent and child nodes for the linked list.
		self.parent = None
		self.children = dict()
Example #7
0
 def default(self, owner):
     return kiwi.Variable(self.name)
Example #8
0
    def constraints(self, component):
        """ Generate the grid constraints for the given component.

        Parameters
        ----------
        component : Constrainable or None
            The constrainable object which represents the conceptual
            owner of the generated constraints.

        Returns
        -------
        result : list
            The list of Constraint objects for the given component.

        """
        # Create the outer boundary box constraints.
        cns = self.box_constraints(component)

        # Compute the cell spans for the items in the grid.
        cells = []
        cell_map = {}
        num_cols = 0
        num_rows = len(self.rows)
        for row_idx, row in enumerate(self.rows):
            num_cols = max(num_cols, len(row))
            for col_idx, item in enumerate(row):
                if item is None:
                    continue
                elif item in cell_map:
                    cell_map[item].expand_to(row_idx, col_idx)
                else:
                    cell = self._Cell(item, row_idx, col_idx)
                    cell_map[item] = cell
                    cells.append(cell)

        # Create the row and column variables and their default limits.
        row_vars = []
        col_vars = []
        for idx in xrange(num_rows + 1):
            var = kiwi.Variable('row%d' % idx)
            row_vars.append(var)
            cns.append(var >= 0)
        for idx in xrange(num_cols + 1):
            var = kiwi.Variable('col%d' % idx)
            col_vars.append(var)
            cns.append(var >= 0)

        # Add the neighbor constraints for the row and column vars.
        for r1, r2 in zip(row_vars[:-1], row_vars[1:]):
            cns.append(r1 <= r2)
        for c1, c2 in zip(col_vars[:-1], col_vars[1:]):
            cns.append(c1 <= c2)

        # Setup the initial interior bounding box for the grid.
        firsts = (self.top, col_vars[-1], row_vars[-1], self.left)
        seconds = (row_vars[0], self.right, self.bottom, col_vars[0])
        for size, first, second in zip(self.margins, firsts, seconds):
            cns.extend(EqSpacer(size).create_constraints(first, second))

        # Setup the spacer lists for constraining the cell items
        row_spacer = FlexSpacer(self.row_spacing / 2)  # floor division
        col_spacer = FlexSpacer(self.column_spacing / 2)
        rspace = [row_spacer] * len(row_vars)
        cspace = [col_spacer] * len(col_vars)
        rspace[0] = rspace[-1] = cspace[0] = cspace[-1] = 0

        # Create the helpers for each constrainable grid cell item. The
        # helper validation is bypassed since the items are known-valid.
        helpers = []
        for cell in cells:
            sr = cell.start_row
            er = cell.end_row + 1
            sc = cell.start_column
            ec = cell.end_column + 1
            item = cell.item
            ritems = (row_vars[sr], rspace[sr], item, rspace[er], row_vars[er])
            citems = (col_vars[sc], cspace[sc], item, cspace[ec], col_vars[ec])
            rhelper = SequenceHelper('bottom', 'top', ())
            chelper = SequenceHelper('right', 'left', ())
            rhelper.items = ritems
            chelper.items = citems
            helpers.extend((rhelper, chelper))
            if isinstance(item, ConstraintHelper):
                helpers.append(item)

        # Add the row alignment helpers if needed. This will only create
        # the helpers for items which do not span multiple rows.
        anchor = self.row_align
        if anchor:
            row_map = defaultdict(list)
            for cell in cells:
                if cell.start_row == cell.end_row:
                    row_map[cell.start_row].append(cell.item)
            for items in row_map.itervalues():
                if len(items) > 1:
                    helper = SequenceHelper(anchor, anchor, (), 0)
                    helper.items = tuple(items)
                    helpers.append(helper)

        # Add the column alignment helpers if needed. This will only
        # create the helpers for items which do not span multiple rows.
        anchor = self.column_align
        if anchor:
            col_map = defaultdict(list)
            for cell in cells:
                if cell.start_column == cell.end_column:
                    col_map[cell.start_column].append(cell.item)
            for items in col_map.itervalues():
                if len(items) > 1:
                    helper = SequenceHelper(anchor, anchor, (), 0)
                    helper.items = tuple(items)
                    helpers.append(helper)

        # Generate the constraints from the helpers.
        for helper in helpers:
            cns.extend(helper.create_constraints(None))

        return cns
Example #9
0
import kiwisolver as kiwi

# 0|-------------| x1 ----- xm ----- x2 |-----------------------|100
x1 = kiwi.Variable('x1')
x2 = kiwi.Variable('x2')
xm = kiwi.Variable('xm')
sm = kiwi.Variable('sm')
sm2 = kiwi.Variable('sm')

constraints = [
    x1 >= 0,
    x2 <= 100,
    x2 >= x1 + 10,
    xm == (x1 + x2) / 2,
    sm == x1 + x2,
]  # these all have strength 'required'

solver = kiwi.Solver()
for cn in constraints:
    solver.addConstraint(cn)

solver.addEditVariable(xm, 'strong')
solver.addEditVariable(sm, 'weak')

solver.addConstraint(sm >= 100)
solver.suggestValue(xm, 40)
solver.updateVariables()
print('x1:', x1.value())
print('x2:', x2.value())
print('xm:', xm.value())
print('sm:', sm.value())
Example #10
0
    def test(self):
        # Setup constrain programming variables.
        fig_w = ks.Variable('figure-width')
        fig_h = ks.Variable('figure-height')
        p1_w = ks.Variable('panel1-width')
        p1_h = ks.Variable('panel1-height')
        p2_w = ks.Variable('panel2-width')
        p2_h = ks.Variable('panel2-height')
        p2a_w = ks.Variable('panel2a-width')
        p2a_h = ks.Variable('panel2a-height')
        p2b_w = ks.Variable('panel2b-width')
        p2b_h = ks.Variable('panel2b-height')
        padding = ks.Variable('padding')

        # Setup solver.
        s = ks.Solver()

        # Setup constraints.
        c1 = fig_w - p1_w == 0
        c2 = fig_w - p2_w == 0
        c3 = p2_w - p2a_w - padding - p2b_w == 0
        c4 = p2a_w - p2b_w == 0
        c5 = fig_h - p1_h - padding - p2_h == 0
        c6 = p2a_h == p2_h
        c7 = p2b_h == p2_h
        c8 = padding == 1.0
        c9 = p1_w == 20.0
        c10 = p1_h == 5.0
        c11 = p2_h == 10.0

        s.addConstraint(c1 | 'strong')
        s.addConstraint(c2 | 'strong')
        s.addConstraint(c3 | 'strong')
        s.addConstraint(c4 | 'strong')
        s.addConstraint(c5 | 'strong')
        s.addConstraint(c6 | 'strong')
        s.addConstraint(c7 | 'strong')
        s.addConstraint(c8 | 'strong')
        s.addConstraint(c9 | 'strong')
        s.addConstraint(c10 | 'strong')
        s.addConstraint(c11 | 'strong')

        s.updateVariables()

        # Check results
        self.assertEqual(fig_w.value(), 20)
        self.assertEqual(fig_h.value(), 16)
        self.assertEqual(p1_w.value(), 20)
        self.assertEqual(p1_h.value(), 5)
        self.assertEqual(p2_w.value(), 20)
        self.assertEqual(p2_h.value(), 10)
        self.assertEqual(p2a_w.value(), 9.5)
        self.assertEqual(p2a_h.value(), 10)
        self.assertEqual(p2b_w.value(), 9.5)
        self.assertEqual(p2b_h.value(), 10)
        self.assertEqual(padding.value(), 1.0)
Example #11
0
def anchorid_to_kv(aid: IAnchorID) -> kiwisolver.Variable:
    return kiwisolver.Variable(str(aid))
Example #12
0
import sys
import time
import math
import os

import kiwisolver as K

import pygame
from pygame.locals import *

from py.util.math import lerp_unlerp

solver = K.Solver()

width = K.Variable("width")
height = K.Variable("height")
pad = K.Variable("pad")

plots_x = K.Variable("plots_x")
plots_y = K.Variable("plots_y")
plot_sz = K.Variable("plot_sz")

solver.addEditVariable(width, "strong")
solver.addEditVariable(height, "strong")
solver.addEditVariable(pad, "strong")

solver.addConstraint(pad <= plots_x)
solver.addConstraint(pad <= plots_y)
solver.addConstraint(plots_x + plot_sz + pad + plot_sz + plots_x == width)
solver.addConstraint(plots_y + plot_sz + plots_y == height)