From c559b4e1257a32dd814fff24301dbd1375746a29 Mon Sep 17 00:00:00 2001 From: "Val Erastov (xibyte)" Date: Mon, 2 Dec 2019 12:12:30 -0800 Subject: [PATCH] signed perpendicular constraint and fillet based on it --- web/app/sketcher/constr/solverConstraints.js | 73 ++++++++++++++++++++ web/app/sketcher/constraints.js | 46 +++++++++++- web/app/sketcher/tools/fillet.js | 12 ---- web/app/sketcher/viewer2d.js | 1 - 4 files changed, 117 insertions(+), 15 deletions(-) diff --git a/web/app/sketcher/constr/solverConstraints.js b/web/app/sketcher/constr/solverConstraints.js index 22e91b21..67074d9d 100644 --- a/web/app/sketcher/constr/solverConstraints.js +++ b/web/app/sketcher/constr/solverConstraints.js @@ -17,6 +17,8 @@ function createByConstraintName(name, params, values) { return new Perpendicular(params); case "parallel": return new Parallel(params); + case "signedPerpendicular": + return new SignedPerpendicular(params); case "P2LDistanceSigned": return new P2LDistanceSigned(params, values[0]); case "P2LDistance": @@ -409,6 +411,77 @@ function P2PDistanceV(params) { } } +function SignedPerpendicular(params) { + + this.params = params; + + const X1 = 0; + const Y1 = 1; + const X2 = 2; + const Y2 = 3; + const X3 = 4; + const Y3 = 5; + const X4 = 6; + const Y4 = 7; + + this.error = function() { + let x1 = params[X1].get(); + let x2 = params[X2].get(); + let y1 = params[Y1].get(); + let y2 = params[Y2].get(); + let x3 = params[X3].get(); + let x4 = params[X4].get(); + let y4 = params[Y4].get(); + let y3 = params[Y3].get(); + + const dx1 = y1 - y2; + const dy1 = x2 - x1; + + const dx2 = x4 - x3; + const dy2 = y4 - y3; + + let c1 = Math.sqrt(sq(dx1) + sq(dy1)); + let c2 = Math.sqrt(sq(dx2) + sq(dy2)); + + return dx1*dx2 + dy1*dy2 - c1 * c2; + }; + + //d(((x-a) * (b - c))^2 ) / dx + + this.gradient = function (out) { + let x1 = params[X1].get(); + let x2 = params[X2].get(); + let y1 = params[Y1].get(); + let y2 = params[Y2].get(); + + let x3 = params[X3].get(); + let x4 = params[X4].get(); + let y3 = params[Y3].get(); + let y4 = params[Y4].get(); + + let dx1 = y1 - y2; + let dy1 = x2 - x1; + + let dx2 = x4 - x3; + let dy2 = y4 - y3; + + let c1 = Math.max(Math.sqrt(sq(dx1) + sq(dy1)), 0.001); + let c2 = Math.max(Math.sqrt(sq(dx2) + sq(dy2)), 0.001); + + out[X1] = y3 - y4 + (c2 * (x2 - x1)) / c1; + out[X2] = y4 - y3 - (c2 * (x2 - x1)) / c1; + out[Y1] = x4 - x3 - (c2 * (y1 - y2)) / c1; + out[Y2] = x3 - x4 + (c2 * (y1 - y2)) / c1; + out[X3] = y2 - y1 + (c1 * (x4 - x3)) / c2; + out[X4] = y1 - y2 - (c1 * (x4 - x3)) / c2; + out[Y3] = x1 - x2 + (c1 * (y4 - y3)) / c2; + out[Y4] = x2 - x1 - (c1 * (y4 - y3)) / c2; + } + this.gradient = NumericGradient; + +} + + function Parallel(params) { this.params = params; diff --git a/web/app/sketcher/constraints.js b/web/app/sketcher/constraints.js index dbb49060..dbf1d26c 100644 --- a/web/app/sketcher/constraints.js +++ b/web/app/sketcher/constraints.js @@ -560,6 +560,44 @@ Constraints.Tangent.prototype.getObjects = function() { return [this.arc, this.line]; }; +// ------------------------------------------------------------------------------------------------------------------ // + +export class SignedPerpendicular extends AbstractConstraint { + + static deserialize(refs, data) { + return new SignedPerpendicular(refs(data[0]), refs(data[1]), refs(data[2]), refs(data[3])); + }; + + constructor(p1, p2, p3, p4) { + super(); + this.points = [p1, p2, p3, p4]; + }; + + + getSolveData() { + const params = []; + this.points.forEach(p => p.collectParams(params)); + return [['signedPerpendicular', params, []]]; + } + + serialize() { + return [this.NAME, this.points.map(p => p.id)]; + } + + getObjects() { + const collector = new Constraints.ParentsCollector(); + this.points.forEach(p => collector.check(p)); + return collector.parents; + } +} + +Constraints.SignedPerpendicular = SignedPerpendicular; +Constraints.SignedPerpendicular.prototype.NAME = 'SignedPerpendicular'; +Constraints.SignedPerpendicular.prototype.UI_NAME = 'SignedPerpendicular'; + +Constraints.Factory[SignedPerpendicular.prototype.NAME] = Coincident.deserialize; + + // ------------------------------------------------------------------------------------------------------------------ // /** @constructor */ @@ -1023,9 +1061,13 @@ Constraints.Fillet = function(point1, point2, arc) { this.point1 = point1; this.point2 = point2; this.arc = arc; + + const line1 = point1.parent; + const line2 = point2.parent; + this.contraints = [ - new Constraints.Tangent( arc, point1.parent), - new Constraints.Tangent( arc, point2.parent), + new Constraints.SignedPerpendicular( arc.a, arc.c, point1, line1.opposite(point1)), + new Constraints.SignedPerpendicular( arc.b, arc.c, line2.opposite(point2), point2), new Constraints.Coincident( arc.a, point1), new Constraints.Coincident( arc.b, point2) ]; diff --git a/web/app/sketcher/tools/fillet.js b/web/app/sketcher/tools/fillet.js index a046b171..f4f8d355 100644 --- a/web/app/sketcher/tools/fillet.js +++ b/web/app/sketcher/tools/fillet.js @@ -69,18 +69,6 @@ export class FilletTool extends Tool { arc.stabilize(this.viewer); pm._add(new Constraints.Fillet( point1, point2, arc)); - this.viewer.validators.push(() => { - function validOn(p, left) { - let op = p.parent.opposite(p); - let opV = op.toVector(); - let dir = p.toVector()._minus(opV)._normalize(); - let centerDir = arc.c.toVector()._minus(opV)._normalize(); - let z = centerDir.cross(dir).z; - - return left ? z < 0.1 : z > -0.1; - } - return validOn(point1, true) && validOn(point2, false); - }); //function otherEnd(point) { // if (point.parent.a.id === point.id) { // return point.parent.b; diff --git a/web/app/sketcher/viewer2d.js b/web/app/sketcher/viewer2d.js index b6d2ba51..d4c094b5 100644 --- a/web/app/sketcher/viewer2d.js +++ b/web/app/sketcher/viewer2d.js @@ -86,7 +86,6 @@ class Viewer { this.historyManager = new HistoryManager(this); this.transformation = null; this.screenToModelMatrix = null; - this.validators = []; this.refresh(); }