Learn R Programming

bezier (version 1.1.2)

bezierCurveFit: Fits a Bezier curve to a set of points

Description

Fits a Bezier curve of any degree and dimension to a set of points. A range or particular number of control points can be specified. If a range of control points is input, bezierCurveFit will find the minimum number of control points required to reach a specified residual standard error threshold. bezierCurveFit is intended to fit a Bezier curve to a large number of sample points, at least double the number of expected Bezier control points, and therefore differs from Bezier curve interpolation, in which the number of sample points are approximately equal to the number of expected Bezier control points.

Usage

bezierCurveFit(m, min.control.points = 3, max.control.points = 20, 
               fix.start.end = FALSE, max.rse = NULL, 
               max.rse.percent.change = 0.01, na.fill = FALSE,
               maxiter = 50, minFactor = 1/1024)

Arguments

m

a vector or matrix of points to which the Bezier curve is to be fit.

min.control.points

the minimum number of control points to use in the curve fit.

max.control.points

the maximum number of control points to use in the curve fit.

fix.start.end

whether the curve fit should be constrained to start and end at the first and last points in m, respectively.

max.rse

the threshold for residual standard error at which curve fitting is stopped.

max.rse.percent.change

the threshold for percent change in residual standard error at which curve fitting is stopped.

na.fill

logical indicating whether missing points (value of NA) in m should be filled by linear interpolation between neighboring non-NA points. Start and end points cannot be NA.

maxiter

a positive integer specifying the maximum number of iterations allowed (to be passed to nls function).

minFactor

a positive numeric value specifying the minimum step-size factor allowed on any step in the iteration (to be passed to nls function).

Value

a list of class 'bezierCurveFit' with the following elements:

p

a list of the control points for the fitted Bezier curve with one element per dimension. p can be input into bezier as the p parameter. See bezier for details on Bezier control point formats.

rse

a vector of the final residual standard error for each dimension.

fit.stopped.by

a vector of the reason curve fitting was stopped (see "Reasons iterations stop" under "Examples").

Details

This function fits a Bezier curve to a vector or matrix of points. If m is a vector, the fitted curve is unidimensional. If m is a matrix, a multidimensional fitted curve is returned (where the number of dimensions is equal to ncol(m)). In either case, the curve fitting is performed on each dimension separately. This can produce different number of control points for each dimension; bezier resolves this through degree elevation (elevateBezierDegree).

min.control.points specifies the minimum number of control points used in the curve fitting while max.control.points specifies the maximum. The number of control points includes the start and end points. If min.control.points is not equal to max.control.points, bezierCurveFit will find the minimum number of control points needed to reach the specified residual standard error threshold. If min.control.points is equal to max.control.points, the number of control points is fixed and bezierCurveFit will perform a single fit using that number of control points. bezierCurveFit is intended to fit a Bezier curve to a large number of sample points, at least double the number of expected Bezier control points, and therefore differs from Bezier curve interpolation, in which the number of sample points are approximately equal to the number of expected Bezier control points.

The nls function is used to find the control point coordinates that minimize the residual standard error (RSE) between the fitted Bezier curve and the input points m. If the number of control points is not fixed, the RSE is found for increasing numbers of control points and used to test for convergence. If the input convergence criteria are met, bezierCurveFit will return the control points at the current iteration. Thus, the number of control points may be less than max.control.points. The two convergence criteria are max.rse and max.rse.percent.change. If the absolute RSE reaches max.rse, bezierCurveFit stops increasing the number of control points and returns the fit at the current iteration.

Once the number of control points exceeds three, regression is used to find the change in RSE as a function of the number of control points. A function is fit to RSE versus the number of control points (a linear function for 3-6 points and a three-parameter exponential function for 7 or more points) to find the rate of change in RSE (the slope). The slope at the current number of control points is divided by the current RSE to find the percent change in RSE. If the percent change in RSE reaches max.rse.percent.change, bezierCurveFit stops increasing the number of control points and returns the fit at the current iteration. If max.rse and max.rse.percent.change are both NULL, bezierCurveFit will continue fitting increasing numbers of control points until max.control.points is reached.

See Also

bezier, pointsOnBezier, elevateBezierDegree

Examples

Run this code
# NOT RUN {
## RUN BEZIER CURVE FIT ON BEZIER CURVE ##
## BEZIER CONTROL POINTS
p <- matrix(c(0,0, 1,4, 2,2, 3,0, 5,5), nrow=5, ncol=2, byrow=TRUE)

## POINTS ON BEZIER
m <- bezier(t=seq(0, 1, length=300), p=p)

## RANDOM VARIATION (NOISE) AROUND POINTS
## SENDING EXACT POINTS WILL ISSUE WARNING IN NLM FUNCTION
mrnorm <- m + cbind(rnorm(nrow(m), 1, 0.1), rnorm(nrow(m), 1, 0.1))

## RESTORE POSITION OF POINTS
mrnorm <- mrnorm - cbind(rep(1, nrow(m)), rep(1, nrow(m)))

## RUN BEZIER CURVE FIT UNCONSTRAINED NUMBER OF CONTROL POINTS
## DEFAULT IS THAT CURVE FIT IS NOT CONSTRAINED TO START AND END POINTS
bfitu <- bezierCurveFit(mrnorm)

## PLOT ORIGINAL BEZIER
plot(m, type="l")

## PLOT POINTS USED IN FITTING
points(mrnorm, col="green", cex=0.25)

## PLOT FIT CURVE
lines(bezier(t=seq(0, 1, length=500), p=bfitu$p), col="red", cex=0.25)
# }

Run the code above in your browser using DataLab