#
luxiaotao1123
2023-03-06 0eec32ca8ceb6d5ddb85eb46a83fa6ca3625306f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import {
    Curve,
    Vector3,
    Vector4
} from '../three.module.js';
import * as NURBSUtils from '../lib/NURBSUtils.js';
 
/**
 * NURBS curve object
 *
 * Derives from Curve, overriding getPoint and getTangent.
 *
 * Implementation is based on (x, y [, z=0 [, w=1]]) control points with w=weight.
 *
 **/
 
class NURBSCurve extends Curve {
 
    constructor(
        degree,
        knots /* array of reals */,
        controlPoints /* array of Vector(2|3|4) */,
        startKnot /* index in knots */,
        endKnot /* index in knots */
    ) {
 
        super();
 
        this.degree = degree;
        this.knots = knots;
        this.controlPoints = [];
        // Used by periodic NURBS to remove hidden spans
        this.startKnot = startKnot || 0;
        this.endKnot = endKnot || ( this.knots.length - 1 );
 
        for ( let i = 0; i < controlPoints.length; ++ i ) {
 
            // ensure Vector4 for control points
            const point = controlPoints[ i ];
            this.controlPoints[ i ] = new Vector4( point.x, point.y, point.z, point.w );
 
        }
 
    }
 
    getPoint( t, optionalTarget = new Vector3() ) {
 
        const point = optionalTarget;
 
        const u = this.knots[ this.startKnot ] + t * ( this.knots[ this.endKnot ] - this.knots[ this.startKnot ] ); // linear mapping t->u
 
        // following results in (wx, wy, wz, w) homogeneous point
        const hpoint = NURBSUtils.calcBSplinePoint( this.degree, this.knots, this.controlPoints, u );
 
        if ( hpoint.w !== 1.0 ) {
 
            // project to 3D space: (wx, wy, wz, w) -> (x, y, z, 1)
            hpoint.divideScalar( hpoint.w );
 
        }
 
        return point.set( hpoint.x, hpoint.y, hpoint.z );
 
    }
 
    getTangent( t, optionalTarget = new Vector3() ) {
 
        const tangent = optionalTarget;
 
        const u = this.knots[ 0 ] + t * ( this.knots[ this.knots.length - 1 ] - this.knots[ 0 ] );
        const ders = NURBSUtils.calcNURBSDerivatives( this.degree, this.knots, this.controlPoints, u, 1 );
        tangent.copy( ders[ 1 ] ).normalize();
 
        return tangent;
 
    }
 
}
 
export { NURBSCurve };