Example #1
0
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))
}
Example #2
0
//
// 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)
}
Example #3
0
// 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)
}
Example #4
0
// 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)
}
Example #5
0
// 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)
}