tangent constraint

This commit is contained in:
Val Erastov 2014-10-13 21:46:18 -07:00
parent 528b25a2e9
commit c18798e079
4 changed files with 132 additions and 2 deletions

View file

@ -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;

View file

@ -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) {

View file

@ -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();
};

View file

@ -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;