← 输入框|github.com|刷新
Skip to content

Circle inexplicably cannot resize more than 16384 #246

Closed

Description

@shrikumarh

System information

solvespace 2.3+repack1-2~bpo8+1

Operating system: (e.g. Debian testing) debian/jessie

Expected behavior

In a sketch with a single circle. a single tangent and an intersecting radial, and no other constraints, all values of circle diameter should be feasible.

Actual behavior

Circle cannot be dragged beyond ~16384.

Hitting space makes the solve error disappear, and then the error strikes again if you so much as touch and move any point.

However, if the sketch is redrawn to scale, with diameter = 1638, then it can be resized happily --- till it reaches ~16384. (or if you start beyond ~16384 diameter).

Additional information

Attached repro bug-earth-resize-stops-at-16384.slvs and working.slvs
bug-earth-resize-stops-at-16384.zip

Activity

  1. changed the title [-]Circle inexplicable cannot resize more than 16384[/-] [+]Circle inexplicably cannot resize more than 16384[/+] on Apr 29, 2017
  2. whitequark commented on Apr 29, 2017

    @whitequark
    Contributor

    Looks like the rank test starts to fail around that diameter (it's ~22354 on my machine, for some reason).

    @shrikumarh The work-around is to enable the "allow redundant constraints" option in the group properties.

    @jwesthues I understand the cause is that RANK_MAG_TOLERANCE is too small for this sketch. Lowering that value to 1e-5 lets the diameter be as large as 225000.

    However, It seems really odd to me that a sketch whose shape doesn't change would fail the rank test at some absolute size and pass at another. The comment above the definition of RANK_MAG_TOLERANCE doesn't seem to apply here. Can you enlighten me?

  3. jwesthues commented on Apr 29, 2017

    @jwesthues
    Member

    RANK_MAG_TOLERANCE is absolute. It should obviously be relative to the bounding box of the sketch; but we have enough dynamic range that it never bothered anyone enough to fix it.

  4. shrikumarh commented on Apr 29, 2017

    @shrikumarh
    Author

    Thanks! Will look forward to fix in some future update.

    Meantime, for me scaling the whole sketch is a better workaround.

    I am using SolveSpace as a "have-fun" graphical-matlab drawing tool for my 8 and 9yo kids to doodle in. The "Redundant Constraints" error message is actually important to me .. it introduces them to notions like degrees of freedom along with solving for sin/cos, years before formal algebra and trigonometry in school.

    SolveSpace is wonderful! Thanks!

  5. jwesthues commented on Apr 29, 2017

    @jwesthues
    Member

    @shrikumarh Thanks, we're glad that you liked it.

    @whitequark I take back my statement above. A tolerance that scaled with the sketch would fix this problem, but introduce new ones with stuff like the quaternions used in assemblies. The right fix is a better rank test in general, like to (a) switch to a test on singular values or similar, and (b) possibly scale particular equations by a factor that scales with the sketch.

  6. Evil-Spirit commented on May 1, 2017

    @Evil-Spirit
    Collaborator

    @jwesthues, I have done it once a time. This is just new operator (Expr::Equals) which substitute Expr::Minus for the cases where we are actually do a comparison not a substraction. And this operation can take epsilon as a fraction of (min/max/mean) bound.

  7. linked a pull request that will close this issueImproved newton (BoykoNeov#4) #1759on Aug 26, 2026
  8. BoykoNeov commented on Aug 27, 2026

    @BoykoNeov
    Contributor

    Written by Claude Opus 5 — both this text and the code it describes; posted by @BoykoNeov.

    Closing note for anyone who arrives here from a search, since this issue was closed as part of the #1759 merge and that isn't quite what fixed it.

    Before the merge I could only say "not demonstrated". In this comment on #1759 I reported that #246 did not reproduce on master when the diameter was driven from 16069 to 50000 — but that this is reported as a dragging bug, and dragging was not a code path my tooling could reach, so I couldn't claim it either way.

    It now is reachable, and it does not reproduce by dragging either. On 3297d9a3, Debug, using a harness that replays a drag through the real GraphicsWindow::MouseLeftDown / MouseMoved / MouseLeftUp path with a solve per frame, on the reporter's own bug-earth-resize-stops-at-16384.slvs:

    • radius dragged 8034.69 → 60000 (diameter 120000, about 7× the reported limit) — every frame OKAY, one degree of freedom left, no rejected constraints
    • five zoom levels, scale 0.003 … 0.3 — no stall, and the achieved radius identical to the last digit across that hundredfold range, so nothing here is limited by pixel resolution
    • 2 / 5 / 20 / 40 / 200 mouse-move steps over the same distance — no difference
    • point drags in the same file, which is the reporter's "if you so much as touch and move any point" — also OKAY throughout

    And the mechanism named in this thread is gone, which settles it better than the drag does. @whitequark's diagnosis above was that RANK_MAG_TOLERANCE is absolute rather than relative to the sketch's bounding box, and @jwesthues' reply was that the right fix is a better rank test in general. That identifier no longer appears anywhere in src/, and there is no comparable hardcoded limit in the geometry code. The rank test was rewritten at some point between 2017 and now.

    So the attribution is off, and it's worth saying plainly. This was already not reproducing on f801618a, i.e. before #1759 — so #1759 is not what fixed it. Whatever rewrote the rank test is. That matters only for the record; nothing live is hidden by the closure, and I'm not suggesting it be reopened.

    Two honest limits. The harness solves on every mouse-move whereas the real GUI drops moves it hasn't repainted since, so it is a finer-grained drag than a human produces — varying the step count from 2 to 200 is only a partial answer to that. And I can't speak for what the reporter's 2017 build did; I can only say what the current one does.

    Method and the rest of the numbers are in this comment on #1761. The harness needed three one-line null-window guards to run headless and is not proposed for merge as it stands.

  9. ruevs commented on Aug 27, 2026

    @ruevs
    Member

    Indeed I confused the matter on this one by testing only that it works with #1759 but did not test if it failed before.

    It is (was) in fact not a dragging issue. Changing the reference dimension of the circle to a normal constraint and typing the value reproduces the problem reliably.

    Here is the real situation:

    Version Fails above [mm]
    2.0, 2.1, 2.2, 2.3 16383.99
    3.0rc1, 3.0rc2, 3.0 22360.67
    3.1, 3.2 2819999.00
    master 3297d9a 7980633.85 as a constraint
    master 3297d9a 5379999.39 as a reference dimension with dragging

    So it seems between 2.3 and 3.0rc1 the 16384 restriction was lifted a bit. Then in 3.1 - when we moved to Eigen for the solver it was improved tremendously. And then #1759 improved it even further.

    But in current master it makes a difference if the dimension is a reference and the size is achieved by dragging or it is a constraint and typed - ~5.38 Km in the first case and ~7.98 Km in the second. This was not the case in 3.2 and older - and this is interesting.

  10. BoykoNeov commented on Aug 27, 2026

    @BoykoNeov
    Contributor

    Written by Claude Opus 5 — both this text and the code it describes; posted by @BoykoNeov.

    @ruevs — your asymmetry reproduces here at both numbers, and chasing it turned up a separate bug that I don't think is known.

    Measured on master 3297d9a3 with the headless drag harness from drag-harness-1761, Debug, on your own bug-earth-resize-stops-at-16384.slvs unmodified. Worth noting the file as attached is your dragging case already: its diameter constraint has reference=1. Flipping that single byte to 0 gives the typed case, and nothing else differs between the two runs.

    how the circle is grown you reported (diameter, mm) measured here
    typed as a driving dimension fails above 7 980 633.85 fails between 7 980 000 and 7 981 000
    dragged, dimension left as reference fails above 5 379 999.39 last OK 5 376 000, first bad 5 389 000

    The dragging limit is a real wall, not an artefact of how I sampled the drag

    That was the first thing I doubted, since a replayed drag has a step size and a real one doesn't. Over the identical path at 15 / 30 / 60 / 120 / 240 / 480 mouse-moves, the last-OK radius climbs to ~2 688 000 and the first-bad falls to ~2 694 500 — converging on your figure from both sides. Refining the drag moves the two bounds together instead of moving the threshold, which is what a genuine limit looks like.

    Zoom is irrelevant too: GraphicsWindow::scale from 0.003 to 0.3, a hundredfold range, gives the same last-OK radius to the last digit. So nothing here is limited by pixel resolution.

    Why dragging gives up ~1.5× earlier

    They aren't the same problem being solved. Dragging puts the circle's distance parameter in sys.dragged, which biases the substitution to hold the value being dragged, and the reference dimension contributes no equation at all. Typing removes that pin and adds the diameter as a driving equation. Two different systems, so two different conditioning limits.

    They're the same failure, though, not two different ones. The dragged case rejects a superset of what the typed case rejects — PT_ON_LINE, PERPENDICULAR and EQUAL_LENGTH_LINES in both, plus VERTICAL and POINTS_COINCIDENT when dragging.

    That's as far as I'd take it. I can say the two systems differ and that the drag's is the worse-conditioned one; I have not measured which term is responsible.

    The thing I wasn't looking for: a failing drag frame cancels the drag

    At the first failing frame the harness reports the drag as still live when MouseMoved returns, and gone immediately after the regenerate that follows. The route:

    SolveSpaceUI::SolveGroupAndReport      src/generate.cpp:530
      -> TextWindow::ReportHowGroupSolved  src/textscreens.cpp:77
         -> SS.GW.ClearSuper()             src/graphicswin.cpp:1421
            -> ClearPending()              src/mouse.cpp:494
    

    ReportHowGroupSolved calls ClearSuper() to switch the property browser to the solve-info screen, and ClearSuper() clears pending — but the user is still holding the mouse button down. So the next MouseMoved takes the pending == NONE branch at src/mouse.cpp:211, starts a fresh drag, calls SS.UndoRemember() and returns without solving anything.

    From then on:

    • every second mouse-move is spent restarting the drag rather than moving anything (the frames alternate, with zero Newton iterations on the restarts);
    • the undo stack collects one entry per restart — 4 in a 60-move drag, 25 in a 480-move one.

    To be clear about the order: the frame has already failed before pending is cleared, so this is not what causes the earlier threshold. But it looks like a good candidate for the "it stops and you can't get it going again" quality of the original report on this issue, and for why a failed drag leaves such a messy undo history.

    I checked and ruled out the obvious suspect: the deleted.requests / deleted.constraints / deleted.groups branch at src/generate.cpp:342, which also calls ClearSuper(), never fires here. Nothing is being deleted; this is purely the report-how-it-solved path.

    Happy to open that as its own issue if you want it tracked — it's independent of everything else here.

    One small thing on your version table

    It settles something I could only guess at. In my comment above I said the mechanism named in the 2017 thread — RANK_MAG_TOLERANCE being absolute rather than relative to the sketch — no longer exists in src/, and that the rank test must have been rewritten "at some point between 2017 and now". Your bisect names the release: 3.1, the move to Eigen, 2.8 M against 3.0's 22 360. That's the same conclusion arrived at from the other end.

    Limits

    Two, both real. The harness solves on every mouse-move, whereas the GUI drops moves it hasn't repainted since — that turns out to matter, and I've now measured it; the numbers are on #1761. And nothing above was run in Release.

    Commands, fixtures and both tables are in test/drag-harness/README.md on the branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions