bezier curve tangent constraint improved

This commit is contained in:
Val Erastov (xibyte) 2020-03-11 16:12:46 -07:00
parent 8254f3dbbb
commit 329af6602f
3 changed files with 70 additions and 11 deletions

View file

@ -4,11 +4,17 @@ import {eqEps, TOLERANCE, TOLERANCE_01, TOLERANCE_SQ} from '../tolerance';
import {fmin_bfgs} from "../../../math/optim";
export function curveStep(curve, u, tessTol, scale) {
tessTol = tessTol || 1;
scale = scale || 1;
let ders = verb.eval.Eval.rationalCurveDerivatives( curve, u, 2 );
let r1 = ders[1];
let r2 = ders[2];
let d1 = ders[1];
let d2 = ders[2];
return genericCurveStep(d1, d2, tessTol, scale);
}
export function genericCurveStep(d1, d2, tessTol = 1, scale = 1) {
let r1 = d1;
let r2 = d2;
let r1lsq = vec.lengthSq(r1);
let r1l = Math.sqrt(r1lsq);
@ -20,6 +26,7 @@ export function curveStep(curve, u, tessTol, scale) {
return step;
}
export function curveDomain(curve) {
return [curve.knots[0], curve.knots[curve.knots.length - 1]];
}

View file

@ -6,8 +6,10 @@ import {COS_FN, Polynomial, POW_1_FN, POW_2_FN, POW_3_FN, SIN_FN} from "./polyno
import {Types} from "../io";
import Vector from "math/vector";
import {cubicBezierDer2, cubicBezierPoint} from "../../brep/geom/curves/bezierCubic";
import {cubicBezierDer1, cubicBezierDer2, cubicBezierPoint} from "../../brep/geom/curves/bezierCubic";
import {greaterThanConstraint, lessThanConstraint} from "./barriers";
import {genericCurveStep} from "../../brep/geom/impl/nurbs-ext";
import {_normalize} from "../../math/vec";
export const ConstraintDefinitions = {
@ -151,16 +153,53 @@ export const ConstraintDefinitions = {
id: 'TangentLineBezier',
name: 'Line & Bezier Tangency',
initialGuess([p0x,p0y, p3x,p3y, p1x,p1y, p2x,p2y, _t, px,py, nx,ny, _ang, ax,ay]) {
const ang = _ang.get();
const p0 = [p0x.get(), p0y.get()];
const p1 = [p1x.get(),p1y.get()];
const p2 = [p2x.get(),p2y.get()];
const p3 = [p3x.get(),p3y.get()];
let t = 0;
let bestT = 0.5;
let best = -1;
while (t <= 1) {
const d1 = cubicBezierDer1(p0, p1, p2, p3, t);
const d2 = cubicBezierDer2(p0, p1, p2, p3, t);
t = Math.min(1, t + (genericCurveStep(d1, d2)||0.1));
_normalize(d2);
const measure = Math.abs(d1[0] * Math.cos(ang) + d1[1] * Math.sin(ang));
if (measure > best) {
best = measure;
bestT = t;
}
if (t === 1) {
break;
}
}
_t.set(bestT);
const [_px, _py] = cubicBezierPoint(p0, p1, p2, p3, bestT);
px.set(_px);
px.set(_py);
},
defineParamsScope: ([segment, curve], callback) => {
const t0 = new Param(0.5, 't');
t0.constraints = [greaterThanConstraint(0), lessThanConstraint(1)];
const [p0, p1, p2, p3] = [curve.p0, curve.p1, curve.p2, curve.p3].map(p => p.toVectorArray());
const [x0, y0] = cubicBezierPoint(p0, p1, p2, p3, t0.get());
const [nx0, ny0] = cubicBezierDer2(p0, p1, p2, p3, t0.get());
const px = new Param(0, 'X');
const py = new Param(0, 'Y');
curve.visitParams(callback);
callback(t0);
callback(new Param(x0, 'X'));
callback(new Param(y0, 'Y'));
callback(px);
callback(py);
callback(new Param(nx0, 'X'));
callback(new Param(ny0, 'Y'));
callback(segment.params.ang);
@ -945,5 +984,11 @@ export class AlgNumConstraint {
}
}
initialGuess() {
if (this.schema.initialGuess) {
this.schema.initialGuess(this.params);
}
}
}

View file

@ -458,9 +458,13 @@ class Isolation {
this.system = system;
this.polynomials = polynomials;
this.beingSolvedParams = new Set();
this.beingSolvedConstraints = new Set();
const residuals = [];
this.polynomials.forEach(p => residuals.push(p.asResidual()));
this.polynomials.forEach(p => {
residuals.push(p.asResidual());
this.beingSolvedConstraints.add(system.polyToConstr.get(p));
});
for (let residual of residuals) {
residual.params.forEach(solverParam => {
@ -495,6 +499,9 @@ class Isolation {
}
solve(rough) {
this.beingSolvedConstraints.forEach(c => c.initialGuess())
this.beingSolvedParams.forEach(solverParam => {
let val = solverParam.objectParam.get();