ellipse tangent constraint math / 'Grater Than' constraint math

This commit is contained in:
Val Erastov 2016-12-06 23:42:38 -08:00
parent 02466e24f7
commit 69da5dcd16

View file

@ -25,6 +25,8 @@ function createByConstraintName(name, params, values) {
return new P2PDistanceV(params);
case "PointOnEllipse":
return new PointOnEllipse(params);
case "EllipseTangent":
return new EllipseTangent(params);
case "angle":
return new Angle(params);
case "angleConst":
@ -33,6 +35,9 @@ function createByConstraintName(name, params, values) {
return new ConstantWrapper(new Angle(params), [x,x,x,x,x,x,x,x,_]);
case 'LockConvex':
return new LockConvex(params);
case 'GreaterThan':
return new GreaterThan(params, values[0]);
}
}
@ -540,6 +545,93 @@ function PointOnEllipse(params) {
this.gradient = NumericGradient;
}
/** @constructor */
function EllipseTangent(params) {
this.params = params;
const P1X = 0;
const P1Y = 1;
const P2X = 2;
const P2Y = 3;
const EP1X = 4;
const EP1Y = 5;
const EP2X = 6;
const EP2Y = 7;
const R = 8;
this.error = function(gr) {
let p1x = params[P1X].get();
let p1y = params[P1Y].get();
let p2x = params[P2X].get();
let p2y = params[P2Y].get();
let ep1x = params[EP1X].get();
let ep1y = params[EP1Y].get();
let ep2x = params[EP2X].get();
let ep2y = params[EP2Y].get();
const radiusY = params[R].get();
let axisX = ep2x - ep1x;
let axisY = ep2y - ep1y;
const radiusX = Math.sqrt(sq(axisX) + sq(axisY)) * 0.5;
const scaleToCircleSpace = radiusY / radiusX;
const rotation = - Math.atan2(axisY, axisX);
function tr(x, y) {
let xx = x * Math.cos(rotation) - y * Math.sin(rotation)
let yy = x * Math.sin(rotation) + y * Math.cos(rotation);
xx *= scaleToCircleSpace;
return {x: xx, y: yy};
}
const axis = tr(axisX, axisY);
const p1 = tr(p1x, p1y);
const p2 = tr(p2x, p2y);
const ep1 = tr(ep1x, ep1y);
const centerX = ep1.x + axis.x * 0.5;
const centerY = ep1.y + axis.y * 0.5;
let normalX = -(p2.y - p1.y);
let normalY = p2.x - p1.x;
const normalD = Math.sqrt(sq(normalX) + sq(normalY));
normalX /= normalD;
normalY /= normalD;
//this length of normal of line to center
let perpendicularLength = (centerX - p1.x) * normalX + (centerY - p1.y) * normalY;
if (perpendicularLength < 0) {
perpendicularLength *= -1;
} else {
}
return (radiusY - perpendicularLength); //*1000;
};
this.gradient = NumericGradient;
}
function GreaterThan(params, limit) {
this.params = params;
this.error = function() {
let value = this.params[0].get();
var error = value <= limit ? limit - value : 0;
console.log("GreaterThan: " + error + ", value: " +value);
return error;
};
this.gradient = function(out) {
out[0] = -1;
}
}
function NumericGradient(out) {
const h = 1;
const approx = (param) => {