Пример #1
0
// Compute the derivatives at a point on a NURBS surface
//
// **params**
// + NurbsSurfaceData object representing the surface
// + number of derivatives to evaluate
// + u parameter at which to evaluate the derivatives
// + v parameter at which to evaluate the derivatives
//
// **returns**
// + a point represented by an array of length (dim)
func (this *NurbsSurface) Derivatives(uv UV, numDerivs int) [][]vec3.T {
	ders := this.nonRationalDerivatives(uv, numDerivs)
	wders := Weight2d(ders)
	skl := make([][]vec3.T, numDerivs+1)

	for k := 0; k <= numDerivs; k++ {
		for l := 0; l <= numDerivs-k; l++ {
			v := ders[k][l].Vec3

			for j := 1; j <= l; j++ {
				scaled := skl[k][l-j].Scaled(binomial(l, j) * wders[0][j])
				v.Sub(&scaled)
			}

			for i := 1; i <= k; i++ {
				scaled := skl[k-i][l].Scaled(binomial(k, i) * wders[i][0])
				v.Sub(&scaled)

				var v2 vec3.T

				for j := 1; j <= l; j++ {
					scaled := skl[k-i][l-j].Scaled(binomial(l, j) * wders[i][j])
					v2.Add(&scaled)
				}

				scaled = v2.Scaled(binomial(k, i))
				v.Sub(&scaled)
			}

			v.Scale(1 / wders[0][0])
			skl[k][l] = v
		}
	}

	return skl
}
Пример #2
0
//
// Compute a point in a non-uniform, non-rational B spline volume
//
// **params**
// + VolumeData
// + u parameter at which to evaluate the volume point
// + v parameter at which to evaluate the volume point
// + w parameter at which to evaluate the volume point
//
// **returns**
// + a point represented by an array of length (dim)
func (this *volume) PointGivenNML(n, m, l int, uvw UVW) vec3.T {
	if !areValidRelations(this.DegreeU, len(this.ControlPoints), len(this.KnotsU)) ||
		!areValidRelations(this.DegreeV, len(this.ControlPoints[0]), len(this.KnotsV)) ||
		!areValidRelations(this.DegreeW, len(this.ControlPoints[0][0]), len(this.KnotsW)) {
		panic("Invalid relations between control points and knot vector")
	}

	controlPoints := this.ControlPoints
	degreeU, degreeV, degreeW := this.DegreeU, this.DegreeV, this.DegreeW
	knotsU, knotsV, knotsW := this.KnotsU, this.KnotsV, this.KnotsW

	knotSpanIndexU := knotsU.SpanGivenN(n, degreeU, uvw[0])
	knotSpanIndexV := knotsV.SpanGivenN(m, degreeV, uvw[1])
	knotSpanIndexW := knotsW.SpanGivenN(l, degreeW, uvw[2])

	uBasisVals := BasisFunctionsGivenKnotSpanIndex(knotSpanIndexU, uvw[0], degreeU, knotsU)
	vBasisVals := BasisFunctionsGivenKnotSpanIndex(knotSpanIndexV, uvw[0], degreeV, knotsV)
	wBasisVals := BasisFunctionsGivenKnotSpanIndex(knotSpanIndexV, uvw[0], degreeW, knotsW)

	uind := knotSpanIndexU - degreeU
	var position, temp, temp2 vec3.T

	for i := 0; i <= degreeW; i++ {
		temp2 = vec3.Zero
		wind := knotSpanIndexW - degreeW + i

		for j := 0; j <= degreeV; j++ {
			temp = vec3.Zero
			vind := knotSpanIndexV - degreeV + j

			for k := 0; k <= degreeU; k++ {
				scaled := controlPoints[uind+k][vind][wind].Scaled(uBasisVals[k])
				temp.Add(&scaled)
			}

			// add weighted contribution of u isoline
			scaled := temp.Scaled(vBasisVals[j])
			temp2.Add(&scaled)
		}

		// add weighted contribution from uv isosurfaces
		scaled := temp2.Scaled(wBasisVals[i])
		position.Add(&scaled)
	}

	return position
}