mirror of
https://github.com/xibyte/jsketcher
synced 2026-02-14 11:30:19 +01:00
ellipse tangent constraint math / 'Grater Than' constraint math
This commit is contained in:
parent
02466e24f7
commit
69da5dcd16
1 changed files with 92 additions and 0 deletions
|
|
@ -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) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue