constraints - geometric constraints on primitive

This modules defines the constraints definitions and the solver tools

Constraints can be any object referencing variables and implementing the following signature to guide the solver in the resolution:

class SomeConstraint:

        # name the attributes referencing the solver variables to change
        slvvars = 'some_primitive', 'some_point'
        # function returning the squared error in the constraint

        #  for a coincident constraint for instance it's the squared distance
        #  the error must be a contiguous function of the parameters, and it's squared for numeric stability reasons.
        #  the solver internally use an iterative approach to optimize the sum of all fit functions.
        def fit((self):

return True if obj match the constraint signature


solve(constraints, fixed=(), *args, **kwargs)

short hand to use the class Problem

class Problem(constraints, fixed=())

class to holds data for a problem solving process. it is intended to be instantiated for each different probleme solving, an instance is used multiple times only when we want to solve on top of the previous results, using exactly the same probleme definition (constraints and variables)

therefore the solver protocol is the follownig:
  • constraints define the probleme

  • each constraint refers to variables it applies on

    constraints have the method fit() and a member ‘slvvars’ that can be

    1. an iterable of names of variable members in the constraint object

    2. a function returning an iterable of the actual variables objects (that therefore must be referenced refs and not primitive types)

  • each variable object can redirect to other variable objects if they implements such a member ‘slvvars’

  • primitives can also be constraints on their variables, thus they must have a method fit() (but no member ‘primitives’ here)

  • primitives can implement the optional solver methods for some constraints, such as ‘slv_tangent’

solving method

Internally, this class uses scipy.optimize.minimize. Therefore the scipy minimization methods using only the gradient are all available. The mose usefull may be:

BFGS fast even for complex problems (few variables)

CG for problems with tons of variables or for nearby solutions

Powell for simple non-continuous problems with tons of variables

default is method='BFGS'


register a constraint or a variable object


unregister all variables from a constraint or a variable object

constraints definitions

class Distance(p1, p2)

Makes two points distant of the fixed given distance

class Radius(arc, radius)

Gets the given Arc with the given fixed radius

Note: Only ArcCentered are supported yet.

class Angle(s1, s2)

Gets two segments with the given fixed angle between them

class Tangent(c1, c2, p)

Makes to curves tangent in the given point The point moves as well as curves.

The curves primitives must have a member slv_tangent(p) returning the tangent vector at the nearest position to p

class OnPlane(axis, pts: list)

Puts the given points on the fixed plane given by its normal axis