jsketcher/modules/geom/curves/nurbsCurve.ts
2020-11-02 19:25:54 -08:00

113 lines
2.9 KiB
TypeScript

import * as ext from '../impl/nurbs-ext';
import {distinctKnots} from '../impl/nurbs-ext';
import {ParametricCurve} from "./parametricCurve";
import {Matrix3x4Data} from "math/matrix";
import {Vec3} from "math/vec";
import {NurbsCurveData} from "geom/curves/nurbsCurveData";
import {CurveBSplineData} from "engine/data/curveData";
//in fact the sketcher format
export interface NurbsSerializaionFormat {
degree: number,
cp: Vec3[],
knots: number[],
weights: number[]
}
export default class NurbsCurve implements ParametricCurve {
verb: any;
data: NurbsCurveData;
static create(degree: number, knots: number[], cp: Vec3[], weights: number[]): NurbsCurve {
// @ts-ignore
return new NurbsCurve(verb.geom.NurbsCurve.byKnotsControlPointsWeights(degree, knots, cp, weights));
}
static deserialize({degree, knots, cp, weights}: NurbsSerializaionFormat): NurbsCurve {
return NurbsCurve.create(degree, knots, cp, weights);
}
constructor(verbCurve) {
this.verb = verbCurve;
this.data = verbCurve.asNurbs();
}
domain(): [number, number] {
return ext.curveDomain(this.data);
}
degree(): number {
return this.data.degree;
}
transform(tr: Matrix3x4Data): ParametricCurve {
const verbCurveTr = this.verb.transform(tr);
return new NurbsCurve(verbCurveTr);
}
point(u: number): Vec3 {
return this.verb.point(u);
}
param(point: Vec3): number {
return this.verb.closestParam(point);
}
eval(u: number, num: number): Vec3[] {
return verb.eval.Eval.rationalCurveDerivatives( this.data, u, num );
}
knots(): number[] {
return distinctKnots(this.data.knots);
}
invert(): ParametricCurve {
let inverted = ext.curveInvert(this.data);
ext.normalizeCurveParametrizationIfNeeded(inverted);
// let [min, max] = curveDomain(curve);
// for (let i = 0; i < reversed.knots.length; i++) {
// if (eqEps(reversed.knots[i], max)) {
// reversed.knots[i] = max;
// } else {
// break;
// }
// }
// for (let i = reversed.knots.length - 1; i >= 0 ; i--) {
// if (eqEps(reversed.knots[i], min)) {
// reversed.knots[i] = min;
// } else {
// break;
// }
// }
return new NurbsCurve(new verb.geom.NurbsCurve(inverted));
}
split(u: number): [ParametricCurve, ParametricCurve] {
let split = verb.eval.Divide.curveSplit(this.data, u);
split.forEach(n => ext.normalizeCurveParametrization(n));
return split.map(c => new NurbsCurve(new verb.geom.NurbsCurve(c)));
}
serialize(): NurbsSerializaionFormat {
return {
degree: this.verb.degree(),
knots: this.verb.knots(),
cp: this.verb.controlPoints(),
weights: this.verb.weights()
}
}
asCurveBSplineData(): CurveBSplineData {
return {
TYPE: "B-SPLINE",
degree: this.verb.degree(),
knots: this.verb.knots(),
cp: this.verb.controlPoints(),
weights: this.verb.weights()
}
}
}