From dedc6d48f475790006f672e6ffd1b2470a6fdd60 Mon Sep 17 00:00:00 2001 From: ruevs Date: Wed, 6 Nov 2024 12:40:10 +0200 Subject: [PATCH] Make pasting mirrored tangent entities independent of end point knowledge The functions Constraint:: ConstrainArcLineTangent ConstrainCubicLineTangent ConstrainCurveCurveTangent were introduced in 96958f466395148ee7f0a252222a2a27e7345c22 in order to properly paste arcs tangent to other objects when mirrored. See the original pull request for details https://github.com/solvespace/solvespace/pull/833 and test files. However these functions use the original logic in constraint.cpp that relies on the two entities sharing an end point. This will interfere implementing tangents on entities without coincident points so I changed the logic to remove the dependency. As a side benefit it makes it cleaner and it's intent more obvious. See https://github.com/solvespace/solvespace/issues/937 --- src/clipboard.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index 0275b1707..e61000de1 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -258,28 +258,31 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { c.valA *= fabs(scale); break; case Constraint::Type::ARC_LINE_TANGENT: { - Entity *line = SK.GetEntity(c.entityB), - *arc = SK.GetEntity(c.entityA); - if(line->type == Entity::Type::ARC_OF_CIRCLE) { - swap(line, arc); + if(scale < 0) { + // When mirroring swap the end point of the arc. The reason is that arcs are + // defined as counter-clockwise from the start point to the end point. And we + // swapped its points in mapPoint above to avoid inverting it. + c.other = !c.other; } - Constraint::ConstrainArcLineTangent(&c, line, arc); break; } case Constraint::Type::CUBIC_LINE_TANGENT: { - Entity *line = SK.GetEntity(c.entityB), - *cubic = SK.GetEntity(c.entityA); - if(line->type == Entity::Type::CUBIC) { - swap(line, cubic); - } - Constraint::ConstrainCubicLineTangent(&c, line, cubic); + // Nothing to do for CUBIC unlike the ARC_OF_CIRCLE above and below. break; } case Constraint::Type::CURVE_CURVE_TANGENT: { - Entity *eA = SK.GetEntity(c.entityA), - *eB = SK.GetEntity(c.entityB); - Constraint::ConstrainCurveCurveTangent(&c, eA, eB); - break; + if(scale < 0) { + // When mirroring swap the end points of arcs. The reason is that arcs are + // defined as counter-clockwise from the start point to the end point. And we + // swapped their points in mapPoint above to avoid inverting them. + // CUBIC splines do not need this. + if(EntityBase::Type::ARC_OF_CIRCLE == SK.GetEntity(c.entityA)->type) { + c.other = !c.other; + } + if(EntityBase::Type::ARC_OF_CIRCLE == SK.GetEntity(c.entityB)->type) { + c.other2 = !c.other2; + } + } } case Constraint::Type::HORIZONTAL: case Constraint::Type::VERTICAL: