mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 18:02:50 +01:00
165 lines
No EOL
4 KiB
JavaScript
165 lines
No EOL
4 KiB
JavaScript
import {Matrix3} from '../../../math/l3space'
|
|
import * as math from '../../../math/math'
|
|
import {Point} from '../point'
|
|
import {Surface} from "../surface";
|
|
import Vector from "../../../math/vector";
|
|
import {Curve} from "../curve";
|
|
|
|
export class NurbsCurve extends Curve {
|
|
|
|
constructor(verbCurve) {
|
|
super();
|
|
this.verb = verbCurve;
|
|
}
|
|
|
|
translate(vector) {
|
|
const tr = new Matrix3().translate(vector.x, vector.y, vector.z).toArray();
|
|
return new NurbsCurve(this.verb.transform(tr));
|
|
}
|
|
|
|
approximate(resolution, from, to, out) {
|
|
const chunks = this.verb.divideByArcLength(10);
|
|
let startU = this.verb.closestParam(from.toArray());
|
|
let endU = this.verb.closestParam(to.toArray());
|
|
const reverse = startU > endU;
|
|
if (reverse) {
|
|
const tmp = startU;
|
|
startU = endU;
|
|
endU = tmp;
|
|
chunks.reverse();
|
|
}
|
|
|
|
for (let sample of chunks) {
|
|
const u = sample.u;
|
|
if (u > startU + math.TOLERANCE && u < endU - math.TOLERANCE) {
|
|
out.push(new Point().set3(this.verb.point(u)));
|
|
}
|
|
}
|
|
}
|
|
|
|
approximateU(resolution, paramFrom, paramTo, consumer) {
|
|
let u = paramFrom;
|
|
let endU = paramTo;
|
|
let step = this.verb.paramAtLength(resolution);
|
|
if (u > endU) {
|
|
step *= -1;
|
|
}
|
|
u += step;
|
|
for (;step > 0 ? u < endU : u > endU; u += step) {
|
|
consumer(u);
|
|
}
|
|
}
|
|
|
|
tangentAtPoint(point) {
|
|
return new Point().set3(this.verb.tangent(this.verb.closestParam(point.data())))._normalize();
|
|
}
|
|
|
|
tangentAtParam(param) {
|
|
return new Point().set3(this.verb.tangent(param ))._normalize();
|
|
}
|
|
|
|
closestDistanceToPoint(point) {
|
|
const closest = this.verb.closestPoint(point.data());
|
|
return math.distance3(point.x, point.y, point.z, closest[0], closest[1], closest[2]);
|
|
}
|
|
|
|
split(point) {
|
|
return this.verb.split(this.verb.closestParam(point.data)).map(v => new NurbsCurve(v));
|
|
}
|
|
|
|
invert() {
|
|
return new NurbsCurve(this.verb.reverse());
|
|
}
|
|
|
|
point(u) {
|
|
return new Point().set3(this.verb.point(u));
|
|
}
|
|
|
|
intersectCurve(other, tol) {
|
|
return verb.geom.Intersect.curves(this.verb, other.verb, tol).map( i => ({
|
|
u0: i.u0,
|
|
u1: i.u1,
|
|
p0: new Vector().set3(i.point0),
|
|
p1: new Vector().set3(i.point1)
|
|
}));
|
|
}
|
|
|
|
static createByPoints(points, degeree) {
|
|
points = points.map(p => p.data());
|
|
return new NurbsCurve(new verb.geom.NurbsCurve.byPoints(points, degeree));
|
|
}
|
|
}
|
|
|
|
NurbsCurve.createLinearNurbs = function(a, b) {
|
|
return new NurbsCurve(new verb.geom.Line(a.data(), b.data()));
|
|
};
|
|
|
|
NurbsCurve.prototype.createLinearNurbs = function(a, b) {
|
|
return NurbsCurve.createLinearNurbs(a, b);
|
|
};
|
|
|
|
export class NurbsSurface extends Surface {
|
|
|
|
constructor(verbSurface) {
|
|
super();
|
|
this.verb = verbSurface;
|
|
this.inverted = false;
|
|
}
|
|
|
|
toNurbs() {
|
|
return this;
|
|
}
|
|
|
|
normal(point) {
|
|
let uv = this.verb.closestParam(point.data());
|
|
let normal = new Vector().set3(this.verb.normal(uv[0], uv[1]));
|
|
if (this.inverted) {
|
|
normal._negate();
|
|
}
|
|
normal._normalize();
|
|
return normal;
|
|
}
|
|
|
|
normalUV(u, v) {
|
|
let normal = new Vector().set3(this.verb.normal(u, v));
|
|
if (this.inverted) {
|
|
normal._negate();
|
|
}
|
|
normal._normalize();
|
|
return normal;
|
|
}
|
|
|
|
normalInMiddle() {
|
|
return this.normalUV(0.5, 0.5);
|
|
}
|
|
|
|
point(u, v) {
|
|
return new Point().set3(this.verb.point(u, v));
|
|
}
|
|
|
|
intersectSurfaceForSameClass(other, tol) {
|
|
const curves = verb.geom.Intersect.surfaces(this.verb, other.verb, tol);
|
|
let inverted = this.inverted !== other.inverted;
|
|
return curves.map(curve => new NurbsCurve(inverted ? curve.reverse() : curve));
|
|
}
|
|
|
|
invert() {
|
|
let inverted = new NurbsSurface(this.verb);
|
|
inverted.inverted = !this.inverted;
|
|
return inverted;
|
|
}
|
|
|
|
isoCurve(param, useV) {
|
|
const data = verb.eval.Make.surfaceIsocurve(this.verb._data, param, useV);
|
|
const isoCurve = new verb.geom.NurbsCurve(data);
|
|
return new NurbsCurve(isoCurve);
|
|
}
|
|
|
|
isoCurveAlignU(param) {
|
|
return this.isoCurve(param, true);
|
|
}
|
|
|
|
isoCurveAlignV(param) {
|
|
return this.isoCurve(param, false);
|
|
}
|
|
} |