mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-07 17:04:58 +01:00
tangent constraint
This commit is contained in:
parent
528b25a2e9
commit
c18798e079
4 changed files with 132 additions and 2 deletions
|
|
@ -12,6 +12,8 @@ TCAD.constraints.create = function(name, params, values) {
|
|||
return new TCAD.constraints.Parallel(params);
|
||||
case "P2LDistance":
|
||||
return new TCAD.constraints.P2LDistance(params, values[0]);
|
||||
case "P2LDistanceV":
|
||||
return new TCAD.constraints.P2LDistanceV(params);
|
||||
case "P2PDistance":
|
||||
return new TCAD.constraints.P2PDistance(params, values[0]);
|
||||
case "P2PDistanceV":
|
||||
|
|
@ -157,6 +159,87 @@ TCAD.constraints.P2LDistance = function(params, distance) {
|
|||
|
||||
};
|
||||
|
||||
|
||||
TCAD.constraints.P2LDistanceV = function(params) {
|
||||
|
||||
this.params = params;//.slice(0, params.length -1);
|
||||
|
||||
var TX = 0;
|
||||
var TY = 1;
|
||||
var LP1X = 2;
|
||||
var LP1Y = 3;
|
||||
var LP2X = 4;
|
||||
var LP2Y = 5;
|
||||
var D = 6;
|
||||
|
||||
this.error = function() {
|
||||
var x0 = this.p0x(), x1 = this.p1x(), x2 = this.p2x();
|
||||
var y0 = this.p0y(), y1 = this.p1y(), y2 = this.p2y();
|
||||
var dist = this.params[D].get();
|
||||
var dx = x2 - x1;
|
||||
var dy = y2 - y1;
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
var area = Math.abs
|
||||
(-x0 * dy + y0 * dx + x1 * y2 - x2 * y1); // = x1y2 - x2y1 - x0y2 + x2y0 + x0y1 - x1y0 = 2*(triangle area)
|
||||
if (d == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (area / d - dist);
|
||||
|
||||
};
|
||||
|
||||
this.p1x = function() {
|
||||
return params[LP1X].get();
|
||||
};
|
||||
|
||||
this.p1y = function() {
|
||||
return params[LP1Y].get();
|
||||
};
|
||||
|
||||
this.p2x = function() {
|
||||
return params[LP2X].get();
|
||||
};
|
||||
|
||||
this.p2y = function() {
|
||||
return params[LP2Y].get();
|
||||
};
|
||||
|
||||
this.p0x = function() {
|
||||
return params[TX].get();
|
||||
};
|
||||
|
||||
this.p0y = function() {
|
||||
return params[TY].get();
|
||||
};
|
||||
|
||||
this.gradient = function(out) {
|
||||
var x0 = this.p0x(), x1 = this.p1x(), x2 = this.p2x();
|
||||
var y0 = this.p0y(), y1 = this.p1y(), y2 = this.p2y();
|
||||
var dx = x2 - x1;
|
||||
var dy = y2 - y1;
|
||||
var d2 = dx * dx + dy * dy;
|
||||
var d = Math.sqrt(d2);
|
||||
var area = -x0 * dy + y0 * dx + x1 * y2 - x2 * y1;
|
||||
out[TX] = ((y1 - y2) / d);
|
||||
out[TY] = ((x2 - x1) / d);
|
||||
out[LP1X] = (((y2 - y0) * d + (dx / d) * area) / d2);
|
||||
out[LP1Y] = (((x0 - x2) * d + (dy / d) * area) / d2);
|
||||
out[LP2X] = (((y0 - y1) * d - (dx / d) * area) / d2);
|
||||
out[LP2Y] = (((x1 - x0) * d - (dy / d) * area) / d2);
|
||||
out[D] = -1;
|
||||
|
||||
for (var i = 0; i < 6; i++) {
|
||||
if (Number.isNaN(out[i])) {
|
||||
out[i] = 0;
|
||||
}
|
||||
if (area < 0) {
|
||||
out[i] *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TCAD.constraints.P2PDistance = function(params, distance) {
|
||||
|
||||
this.params = params;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,25 @@ TCAD.TWO.ParametricManager.prototype._fetchPointAndLine = function(objs) {
|
|||
return [point, line];
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype._fetchArcAndLine = function(objs) {
|
||||
|
||||
var arc = null;
|
||||
var line = null;
|
||||
|
||||
for (var i = 0; i < objs.length; ++i) {
|
||||
if (objs[i]._class == 'TCAD.TWO.Arc') {
|
||||
arc = objs[i];
|
||||
} else if (objs[i]._class == 'TCAD.TWO.Segment') {
|
||||
line = objs[i];
|
||||
}
|
||||
}
|
||||
if (arc == null || line == null) {
|
||||
throw "Illegal Argument. Constraint requires arc and line."
|
||||
}
|
||||
|
||||
return [arc, line];
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype._fetchTwoLines = function(objs) {
|
||||
var lines = [];
|
||||
for (var i = 0; i < objs.length; ++i) {
|
||||
|
|
|
|||
|
|
@ -99,9 +99,13 @@ TCAD.App2D = function() {
|
|||
|
||||
"R = R" : function() {
|
||||
app.viewer.parametricManager.rr(app.viewer.selected);
|
||||
}
|
||||
},
|
||||
|
||||
tangent : function() {
|
||||
app.viewer.parametricManager.tangent(app.viewer.selected);
|
||||
}
|
||||
};
|
||||
|
||||
actionsF.add(actions, 'addSegment');
|
||||
actionsF.add(actions, 'addArc');
|
||||
actionsF.add(actions, 'pan');
|
||||
|
|
@ -115,6 +119,7 @@ TCAD.App2D = function() {
|
|||
actionsF.add(actions, 'P2PDistance');
|
||||
actionsF.add(actions, 'Radius');
|
||||
actionsF.add(actions, 'R = R');
|
||||
actionsF.add(actions, 'tangent');
|
||||
actionsF.open();
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,6 +32,13 @@ TCAD.TWO.ParametricManager.prototype.perpendicular = function(objs) {
|
|||
this.add(new TCAD.TWO.Constraints.Perpendicular(lines[0], lines[1]));
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.tangent = function(objs) {
|
||||
var al = this._fetchArcAndLine(objs);
|
||||
var arc = al[0];
|
||||
var line = al[1];
|
||||
this.add(new TCAD.TWO.Constraints.P2LDistanceV( arc.c, line, arc.r ));
|
||||
};
|
||||
|
||||
TCAD.TWO.ParametricManager.prototype.rr = function(objs) {
|
||||
var arcs = this._fetchArcs(objs, 2);
|
||||
var prev = arcs[0].r;
|
||||
|
|
@ -72,7 +79,7 @@ TCAD.TWO.ParametricManager.prototype.p2pDistance = function(objs, promptCallback
|
|||
var p = this._fetchTwoPoints(objs);
|
||||
var distance = new TCAD.Vector(p[1].x - p[0].x, p[1].y - p[0].y).length();
|
||||
var promptDistance = promptCallback("Enter the distance", distance.toFixed(2));
|
||||
|
||||
|
||||
if (promptDistance != null) {
|
||||
promptDistance = Number(promptDistance);
|
||||
if (promptDistance == promptDistance) { // check for NaN
|
||||
|
|
@ -296,6 +303,22 @@ TCAD.TWO.Constraints.P2LDistance.prototype.getSolveData = function() {
|
|||
return ['P2LDistance', params, [this.d]];
|
||||
};
|
||||
|
||||
|
||||
TCAD.TWO.Constraints.P2LDistanceV = function(p, l, d) {
|
||||
this.p = p;
|
||||
this.l = l;
|
||||
this.d = d;
|
||||
};
|
||||
|
||||
TCAD.TWO.Constraints.P2LDistanceV.prototype.getSolveData = function() {
|
||||
var params = [];
|
||||
this.p.collectParams(params);
|
||||
this.l.collectParams(params);
|
||||
params.push(this.d);
|
||||
return ['P2LDistanceV', params];
|
||||
};
|
||||
|
||||
|
||||
TCAD.TWO.Constraints.P2PDistance = function(p1, p2, d) {
|
||||
this.p1 = p1;
|
||||
this.p2 = p2;
|
||||
|
|
|
|||
Loading…
Reference in a new issue