CadQuery / cadquery

A python parametric CAD scripting framework based on OCCT
https://cadquery.readthedocs.io
Other
3.2k stars 290 forks source link

Sketch solver does not converge Angle constraint with bad starting point #960

Open lorenzncode opened 2 years ago

lorenzncode commented 2 years ago

Example of "bad" or problematic starting point:

    .segment((0, 0), (1.0, 0), "seg1")
    .segment((0, 0), (-1.0, 0.0), "seg2")
    .constrain("seg1", "seg2", "Angle", 30)

Another example with segment-arc when tangents are opposite:

    .segment((-0.5, -2), (-0.5, 0.0), "seg1")
    .arc((-0.5, 0.0), (0.0, -0.5), (0.5, 0.0), "arc1")
    .constrain("seg1", "arc1", "Coincident", None)
    .constrain("seg1", "arc1", "Angle", 30)

Starting point before solve: image

I'm testing a fix for this issue by checking if the tangent vectors are opposite, then rotating one of the vectors to push the optimizer in one direction (maybe need to check parallel for other cases):

        if v1.IsOpposite(v2,TOL/2):
            v1 = v1.Rotated(TOL)

So far this appears to be working in my testing.

image

adam-urbanczyk commented 2 years ago

Yup that can happen - we are using a numerical solver. I'm not sure that I understand your proposal. I'd be against arbitrarily changing the starting point.

lorenzncode commented 2 years ago

Would you be against changing angle_cost to address this? https://github.com/CadQuery/cadquery/blob/4fcada66e9fb5d8cebfdf78376154b7b253df991/cadquery/occ_impl/sketch_solver.py#L136

Say by rotating the tangent vector v1 by TOL based on the IsOpposite check?

        if v1.IsOpposite(v2,TOL/2):
            v1 = v1.Rotated(TOL)