func NurbsCurveByPoints(points []vec3.T, _degree *int) *verb.NurbsCurve { var degree int if _degree == nil { degree = 3 } else { degree = *_degree } return verb.NewNurbsCurveUnchecked(interpCurve(points, degree, nil, nil)) }
// // 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) }
// generate the control points, weights, and knots for a bezier curve of any degree // // **params** // + first point in counter-clockwise form // + second point in counter-clockwise form // + third point in counter-clockwise form // + forth point in counter-clockwise form // // **returns** // + nurbssurfacedata object func BezierCurve(controlPoints []vec3.T) *verb.NurbsCurve { degree := len(controlPoints) - 1 // build uniform weights weights := make([]float64, len(controlPoints)) for i := range weights { weights[i] = 1 } knots := make([]float64, 2*degree+2) for i := range knots[len(knots)/2:] { knots[i] = 1 } return verb.NewNurbsCurveUnchecked(degree, controlPoints, weights, knots) }
// Generate the control points, weights, and knots of a polyline curve // // **params** // + array of points in curve // // **returns** // + a NurbsCurveData object representing a NURBS curve func Polyline(pts []vec3.T) *verb.NurbsCurve { knots := make([]float64, len(pts)+1) var lsum float64 for i := 0; i < len(pts)-1; i++ { lsum += vec3.Distance(&pts[i], &pts[i+1]) knots[i+2] = lsum } knots[len(knots)-1] = lsum // normalize the knot array for i := range knots { knots[i] /= lsum } weights := make([]float64, len(pts)) for i := range weights { weights[i] = 1 } return verb.NewNurbsCurveUnchecked(1, pts, weights, knots) }
// Generate the control points, weights, and knots of an elliptical arc // // **params** // + the center // + the scaled x axis // + the scaled y axis // + start angle of the ellipse arc, between 0 and 2pi, where 0 points at the xaxis // + end angle of the arc, between 0 and 2pi, greater than the start angle // // **returns** // + a NurbsCurveData object representing a NURBS curve func EllipseArc(center *vec3.T, xaxis, yaxis *vec3.T, startAngle, endAngle float64) *verb.NurbsCurve { xradius, yradius := xaxis.Length(), yaxis.Length() xaxisNorm, yaxisNorm := xaxis.Normalized(), yaxis.Normalized() // if the end angle is less than the start angle, do a circle if endAngle < startAngle { endAngle = 2.0*math.Pi + startAngle } theta := endAngle - startAngle // how many arcs? var numArcs int if theta <= math.Pi/2 { numArcs = 1 } else { if theta <= math.Pi { numArcs = 2 } else if theta <= 3*math.Pi/2 { numArcs = 3 } else { numArcs = 4 } } dtheta := theta / float64(numArcs) w1 := math.Cos(dtheta / 2) xCompon := xaxisNorm.Scaled(xradius * math.Cos(startAngle)) yCompon := yaxisNorm.Scaled(yradius * math.Sin(startAngle)) P0 := vec3.Add(&xCompon, &yCompon) temp0 := yaxisNorm.Scaled(math.Cos(startAngle)) temp1 := xaxisNorm.Scaled(math.Sin(startAngle)) T0 := vec3.Sub(&temp0, &temp1) controlPoints := make([]vec3.T, 2*numArcs+1) knots := make([]float64, 2*numArcs+3) index := 0 angle := startAngle weights := make([]float64, numArcs*2) controlPoints[0] = P0 weights[0] = 1.0 for i := 1; i <= numArcs; i++ { angle += dtheta xCompon = xaxisNorm.Scaled(xradius * math.Cos(angle)) yCompon = yaxisNorm.Scaled(yradius * math.Sin(angle)) offset := vec3.Add(&xCompon, &yCompon) P2 := vec3.Add(center, &offset) weights[index+2] = 1 controlPoints[index+2] = P2 temp0 := yaxisNorm.Scaled(math.Cos(angle)) temp1 := xaxisNorm.Scaled(math.Sin(angle)) T2 := vec3.Sub(&temp0, &temp1) T0Norm := T0.Normalized() T2Norm := T2.Normalized() inters := intersect.Rays(&P0, &T0Norm, &P2, &T2Norm) T0Scaled := T0.Scaled(inters.U0) P1 := vec3.Add(&P0, &T0Scaled) weights[index+1] = w1 controlPoints[index+1] = P1 index += 2 if i < numArcs { P0 = P2 T0 = T2 } } j := 2*numArcs + 1 for i := 0; i < 3; i++ { knots[i] = 0.0 knots[i+j] = 1.0 } switch numArcs { case 2: knots[3] = 0.5 knots[4] = 0.5 case 3: knots[3] = 1 / 3 knots[4] = 1 / 3 knots[5] = 2 / 3 knots[6] = 2 / 3 case 4: knots[3] = 0.25 knots[4] = 0.25 knots[5] = 0.5 knots[6] = 0.5 knots[7] = 0.75 knots[8] = 0.75 } return verb.NewNurbsCurveUnchecked(2, controlPoints, weights, knots) }