mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-24 09:26:43 +01:00
fillet tool
This commit is contained in:
parent
8d19130bb9
commit
43986faa22
8 changed files with 203 additions and 9 deletions
|
|
@ -18,7 +18,7 @@ TCAD.math.QR = function(matrix) {
|
|||
var vec = TCAD.math.vec;
|
||||
this.matrix = matrix;
|
||||
var nR = this.matrix.length;
|
||||
var nC = this.matrix[0].length;
|
||||
var nC = nR == 0 ? 0 : this.matrix[0].length;
|
||||
|
||||
this.qrRankingThreshold = 1e-30; //??
|
||||
this.solvedCols = Math.min(nR, nC);
|
||||
|
|
|
|||
|
|
@ -50,10 +50,31 @@ TCAD.Vector.prototype.minus = function(vector) {
|
|||
return new TCAD.Vector(this.x - vector.x, this.y - vector.y, this.z - vector.z);
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype._minus = function(vector) {
|
||||
this.x -= vector.x;
|
||||
this.y -= vector.y;
|
||||
this.z -= vector.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype._minusXYZ = function(x, y, z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
return this;
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype.plus = function(vector) {
|
||||
return new TCAD.Vector(this.x + vector.x, this.y + vector.y, this.z + vector.z);
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype._plus = function(vector) {
|
||||
this.x += vector.x;
|
||||
this.y += vector.y;
|
||||
this.z += vector.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype.normalize = function() {
|
||||
var mag = this.length();
|
||||
if (mag == 0.0) {
|
||||
|
|
|
|||
|
|
@ -206,6 +206,12 @@ TCAD.parametric.lock2Equals2 = function(constrs, locked) {
|
|||
};
|
||||
|
||||
TCAD.parametric.diagnose = function(sys) {
|
||||
if (sys.constraints.length == 0 || sys.params.length == 0) {
|
||||
return {
|
||||
conflict : false,
|
||||
dof : 0
|
||||
}
|
||||
}
|
||||
var jacobian = sys.makeJacobian();
|
||||
var qr = new TCAD.math.QR(jacobian);
|
||||
return {
|
||||
|
|
@ -231,13 +237,18 @@ TCAD.parametric.prepare = function(constrs, locked, aux, alg) {
|
|||
sys.setParams(point);
|
||||
return sys.makeJacobian();
|
||||
};
|
||||
var nullResult = {
|
||||
evalCount : 0,
|
||||
error : 0,
|
||||
returnCode : 1
|
||||
};
|
||||
|
||||
function solve(rough, alg) {
|
||||
if (constrs.length == 0) return;
|
||||
if (sys.params.length == 0) return;
|
||||
if (constrs.length == 0) return nullResult;
|
||||
if (sys.params.length == 0) return nullResult;
|
||||
if (TCAD.parametric.diagnose(sys).conflict) {
|
||||
console.log("Conflicting or redundant constraints. Please fix your system.");
|
||||
return;
|
||||
return nullResult;
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
|
|
|
|||
|
|
@ -102,3 +102,24 @@ TCAD.TWO.ParametricManager.prototype._fetchTwoLines = function(objs) {
|
|||
}
|
||||
return lines;
|
||||
};
|
||||
|
||||
TCAD.TWO.utils._fetchSketchObjects = function(objs, silent, matching) {
|
||||
var fetched = [];
|
||||
for (var i = 0; i < objs.length; ++i) {
|
||||
for (var j = 0; j < matching.length; j++) {
|
||||
if (objs[i]._class == matching[j]) {
|
||||
fetched[j] = objs[i];
|
||||
matching[j] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fetched.length != matching.length) {
|
||||
if (silent) {
|
||||
return null;
|
||||
} else {
|
||||
throw "Illegal Argument. " + matching + " required";
|
||||
}
|
||||
}
|
||||
return fetched;
|
||||
};
|
||||
|
||||
|
|
|
|||
123
web/app/sketcher/helpers.js
Normal file
123
web/app/sketcher/helpers.js
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
|
||||
TCAD.TWO.FilletTool = function(viewer) {
|
||||
this.viewer = viewer;
|
||||
};
|
||||
|
||||
TCAD.TWO.FilletTool.prototype.makeFillet = function(point1, point2) {
|
||||
function shrink(point1) {
|
||||
point1.parent.a;
|
||||
if (point1.id === point1.parent.a.id) {
|
||||
var a = point1.parent.b;
|
||||
var b = point1.parent.a;
|
||||
} else {
|
||||
var a = point1.parent.a;
|
||||
var b = point1.parent.b;
|
||||
}
|
||||
var d = TCAD.math.distanceAB(a, b);
|
||||
k = 4 / 5;
|
||||
b.x = a.x + (b.x - a.x) * k;
|
||||
b.y = a.y + (b.y - a.y) * k;
|
||||
return new TCAD.Vector(a.x - b.x, a.y - b.y, 0);
|
||||
}
|
||||
|
||||
var v1 = shrink(point1);
|
||||
var v2 = shrink(point2);
|
||||
|
||||
if (v1.cross(v2).z > 0) {
|
||||
var _ = point1;
|
||||
point1 = point2;
|
||||
point2 = _;
|
||||
}
|
||||
|
||||
var vec = new TCAD.Vector();
|
||||
vec.setV(point2);
|
||||
vec._minus(point1);
|
||||
vec._multiply(0.5);
|
||||
vec._plus(point1);
|
||||
|
||||
var arc = new TCAD.TWO.Arc(
|
||||
new TCAD.TWO.EndPoint(point1.x, point1.y),
|
||||
new TCAD.TWO.EndPoint(point2.x, point2.y),
|
||||
new TCAD.TWO.EndPoint(vec.x, vec.y))
|
||||
point1.parent.layer.objects.push(arc);
|
||||
var pm = this.viewer.parametricManager;
|
||||
arc.stabilize(this.viewer);
|
||||
pm._add(new TCAD.TWO.Constraints.Tangent( arc, point1.parent));
|
||||
pm._add(new TCAD.TWO.Constraints.Tangent( arc, point2.parent));
|
||||
pm._add(new TCAD.TWO.Constraints.Coincident( arc.a, point1));
|
||||
pm._add(new TCAD.TWO.Constraints.Coincident( arc.b, point2));
|
||||
|
||||
var solver = pm.solveWithLock([]);
|
||||
// var solver = pm.solveWithLock([point1._x, point1._y, point2._x, point2._y]);
|
||||
pm.notify();
|
||||
this.viewer.refresh();
|
||||
};
|
||||
|
||||
TCAD.TWO.FilletTool.prototype.mouseup = function(e) {
|
||||
var candi = this.getCandidate(e);
|
||||
if (candi == null) return;
|
||||
var point1 = candi[0];
|
||||
var point2 = candi[1];
|
||||
|
||||
var pm = this.viewer.parametricManager;
|
||||
for (var i = 0; i < pm.subSystems.length; i++) {
|
||||
var subSys = pm.subSystems[i];
|
||||
for (var j = 0; j < subSys.constraints.length; j++) {
|
||||
var c = subSys.constraints[j];
|
||||
if (c.NAME === 'coi' &&
|
||||
((c.a.id === point1.id && c.b.id === point2.id) ||
|
||||
(c.b.id === point1.id && c.a.id === point2.id))) {
|
||||
pm.remove(c);
|
||||
this.makeFillet(point1, point2);
|
||||
this.viewer.deselectAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.TWO.FilletTool.prototype.getCandidate = function(e) {
|
||||
var picked = this.viewer.pick(e);
|
||||
if (picked.length > 0) {
|
||||
function isLine(line) {
|
||||
return line != null && line._class === 'TCAD.TWO.Segment';
|
||||
}
|
||||
var res = TCAD.TWO.utils._fetchSketchObjects(picked, true, ['TCAD.TWO.EndPoint']);
|
||||
if (res == null) return null;
|
||||
var point1 = res[0];
|
||||
if (!isLine(point1.parent)) return;
|
||||
var line2 = null;
|
||||
for (var i = 0; i < point1.linked.length; i++) {
|
||||
var point2 = point1.linked[i];
|
||||
if (isLine(point2.parent)) {
|
||||
return [point1, point2];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
TCAD.TWO.FilletTool.prototype.keydown = function(e) {};
|
||||
TCAD.TWO.FilletTool.prototype.keypress = function(e) {};
|
||||
TCAD.TWO.FilletTool.prototype.keyup = function(e) {};
|
||||
TCAD.TWO.FilletTool.prototype.cleanup = function(e) {};
|
||||
|
||||
TCAD.TWO.FilletTool.prototype.mousemove = function(e) {
|
||||
var needRefresh = false;
|
||||
if (this.viewer.selected.length != 0) {
|
||||
this.viewer.deselectAll();
|
||||
needRefresh = true;
|
||||
}
|
||||
var candi = this.getCandidate(e);
|
||||
if (candi != null) {
|
||||
this.viewer.mark(candi[0], TCAD.TWO.Styles.SNAP);
|
||||
needRefresh = true;
|
||||
}
|
||||
if (needRefresh) {
|
||||
this.viewer.refresh();
|
||||
}
|
||||
};
|
||||
TCAD.TWO.FilletTool.prototype.mousedown = function(e) {};
|
||||
TCAD.TWO.FilletTool.prototype.mousewheel = function(e) {};
|
||||
|
||||
|
|
@ -41,6 +41,10 @@ TCAD.App2D = function() {
|
|||
this.registerAction('pan', "Pan", function () {
|
||||
app.viewer.toolManager.releaseControl();
|
||||
});
|
||||
|
||||
this.registerAction('addFillet', "Add Fillet", function () {
|
||||
app.viewer.toolManager.takeControl(new TCAD.TWO.FilletTool(app.viewer));
|
||||
});
|
||||
|
||||
this.registerAction('addDim', "Add Dimension", function () {
|
||||
app.viewer.toolManager.takeControl(new TCAD.TWO.AddDimTool(app.viewer, app.viewer.dimLayer, function(a,b) {return new TCAD.TWO.Dimension(a,b)} ));
|
||||
|
|
|
|||
|
|
@ -298,6 +298,12 @@ TCAD.TWO.ParametricManager.prototype.solve = function() {
|
|||
solver.sync();
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.solveWithLock = function(lock) {
|
||||
var solver = this.prepare(lock);
|
||||
solver.solve(false);
|
||||
solver.sync();
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.prepare = function(locked) {
|
||||
return this._prepare(locked, this.subSystems);
|
||||
};
|
||||
|
|
@ -313,11 +319,12 @@ TCAD.TWO.ParametricManager.prototype._prepare = function(locked, subSystems) {
|
|||
solve : function(rough) {
|
||||
for (var i = 0; i < solvers.length; i++) {
|
||||
var alg = subSystems[i].alg;
|
||||
if (solvers[i].solve(rough, alg) !== 1) {
|
||||
//alg = alg == 1 ? 2 : 1;
|
||||
//if (solvers[i].solve(rough, alg) == 1) {
|
||||
// subSystems[i].alg = alg;
|
||||
//}
|
||||
var res = solvers[i].solve(rough, alg);
|
||||
if (res.returnCode !== 1) {
|
||||
alg = alg == 1 ? 2 : 1;
|
||||
if (solvers[i].solve(rough, alg).returnCode == 1) {
|
||||
subSystems[i].alg = alg;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -351,6 +358,11 @@ TCAD.TWO.ParametricManager.prototype.prepareForSubSystem = function(locked, subS
|
|||
return Math.abs(p1.get() - p2.get()) <= 0.000001
|
||||
}
|
||||
var system = this.__getSolveData(subSystem, []);
|
||||
system.sort(function(a, b){
|
||||
a = a[0] === 'equal' ? 1 : 2;
|
||||
b = b[0] === 'equal' ? 1 : 2;
|
||||
return a - b;
|
||||
});
|
||||
var tuples = [];
|
||||
for (i = 0; i < system.length; ++i) {
|
||||
var c = system[i];
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@
|
|||
<script src="app/sketcher/shapes/circle.js"></script>
|
||||
<script src="app/sketcher/shapes/segment.js"></script>
|
||||
<script src="app/sketcher/shapes/dim.js"></script>
|
||||
<script src="app/sketcher/helpers.js"></script>
|
||||
|
||||
<script src="app/math/vector.js"></script>
|
||||
<script src="app/math/math.js"></script>
|
||||
|
|
@ -274,6 +275,7 @@
|
|||
--><button class="btn tbtn act-addMultiSegment" style="background-image: url(img/mline.png);" type="submit" value=""></button><!--
|
||||
--><button class="btn tbtn act-addCircle" style="background-image: url(img/circle.png);" type="submit" value=""></button><!--
|
||||
--><button class="btn tbtn act-addArc sep" style="background-image: url(img/arc.png);" type="submit" value=""></button><!--
|
||||
--><button class="btn tbtn act-addFillet sep" type="submit" value="">F</button><!--
|
||||
--><button class="btn tbtn act-addHDim" style="background-image: url(img/hdim.png);" type="submit" value=""></button><!--
|
||||
--><button class="btn tbtn act-addVDim" style="background-image: url(img/vdim.png);" type="submit" value=""></button><!--
|
||||
--><button class="btn tbtn act-addDim" style="background-image: url(img/dim.png);" type="submit" value=""></button><!--
|
||||
|
|
|
|||
Loading…
Reference in a new issue