// // Generate the control points, weights, and knots of a cone // // **params** // + normalized axis of cone // + position of base of cone // + height from base to tip // + radius at the base of the cone // // **returns** // + an object with the following properties: controlPoints, weights, knots, degree // func ConicalSurface(axis, xaxis *vec3.T, base *vec3.T, height, radius float64) *verb.NurbsSurface { angle := 2 * math.Pi profDegree := 1 heightCompon := axis.Scaled(height) radiusCompon := xaxis.Scaled(radius) profCtrlPts := []vec3.T{vec3.Add(base, &heightCompon), vec3.Add(base, &radiusCompon)} profKnots := []float64{0, 0, 1, 1} profWeights := []float64{1, 1} prof := verb.NewNurbsCurveUnchecked(profDegree, profCtrlPts, profWeights, profKnots) return RevolvedSurface(prof, base, axis, angle) }
// // 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 }
// 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 }
func Homogenized(pt vec3.T, w float64) HomoPoint { return HomoPoint{pt.Scaled(w), w} }
// Generate the control points, weights, and knots of an arbitrary arc // (Corresponds to Algorithm A7.1 from Piegl & Tiller) // // **params** // + the center of the arc // + the xaxis of the arc // + orthogonal yaxis of the arc // + radius of the arc // + start angle of the arc, between 0 and 2pi // + end angle of the arc, between 0 and 2pi, greater than the start angle // // **returns** // + a NurbsCurveData object representing a NURBS curve func Arc(center *vec3.T, xaxis, yaxis *vec3.T, radius float64, startAngle, endAngle float64) *verb.NurbsCurve { xaxisScaled, yaxisScaled := xaxis.Scaled(radius), yaxis.Scaled(radius) return EllipseArc(center, &xaxisScaled, &yaxisScaled, startAngle, endAngle) }