Code covered by the BSD License  

Highlights from
cubic Bezier least square fitting

image thumbnail
from cubic Bezier least square fitting by Dr. Murtaza Khan
Approximation of data using cubic Bezier curve least square fitting

FindBezierControlPointsND(p,varargin)
% INPUT
% Data: A set of "n" points (p1,p2,...pn).
% Each point can be in N-dimension vector space
% % (i.e. points to be approximated by Cubic Bezier Curve
%       e.g. p for 3D p=[0   5   0;      % p1
%                        1   5   0.5;    % p2
%                        1.3 4.5 1;      % p3
%                        2   5   2]      % p4
% ptype(optional arg): parameterization type, defualt is chord-length
% parameterization. user can pass 'u' or 'uniform', for uniform parameterization.

% OUTPUT
% Four Control Points: P0, P1, P2, P3, each in N-dimension space
%  parameterized values i.e. t (optional)

% OBJECTIVE
% We want to find control points of Bezier Curve that fit the data
% p.

% SOLUTION
% Least Square Method using specified Parameterization (Chord-length
% defualt)
% (P0 & P3) are end points of a bezier curve segment. So they
% are taken equal to first and last point of data. 
% (P1 & P2) are obtained by partially differeciating the Sum of Square
% distance between original data and parametric curve w.r.t P1 & P2 and then
% solving for two unknowns P1 & P2.

function [P0, P1, P2, P3, tout]= FindBezierControlPointsND(p,varargin)

%%% Default Values %%%
ptype='';
defaultValues = {ptype};
%%% Assign Valus %%%
nonemptyIdx = ~cellfun('isempty',varargin);
defaultValues(nonemptyIdx) = varargin(nonemptyIdx);
[ptype] = deal(defaultValues{:});
%%%------------------------------

n=size(p,1);              % number of rows in p

if (strcmpi(ptype,'u') || strcmpi(ptype,'uniform') )
    [t]=linspace(0,1,n);      % uniform parameterized values (normalized b/w 0 to 1)
else
    [t]=ChordLengthNormND(p); % chord-length parameterized values (normalized b/w 0 to 1)
end

P0=p(1,:);       % (at t=0 => P0=p1)
P3=p(n,:);       % (at t=1 => P3=pn)

if (n==1)      % if only one value in p
   P1=P0;      % P1=P0
   P2=P0;      % P2=P0
   
elseif (n==2)  % if only two values in p
   P1=P0;      % P1=P0
   P2=P3;      % P2=P3
   
elseif (n==3)  % if only three values in p
   P1=p(2,:);    % middle point is P1
   P2=p(2,:);    % middle point is P2

else
    
   A1=0;	A2=0;	A12=0;	C1=0;	C2=0; %initialization
    for i=2:n-1 
%    for i=1:n    %it will give same CPs as   i=2:n-1   
      B0 = (1-t(i))^3            ;        % Bezeir Basis
      B1 = ( 3*t(i)*(1-t(i))^2 ) ;
      B2 = ( 3*t(i)^2*(1-t(i)) ) ;
      B3 = t(i)^3                ;
      
      A1  = A1 +  B1^2;
      A2  = A2 +  B2^2;
      A12 = A12 + B1*B2;
      C1 = C1 + B1*( p(i,:) - B0*P0 - B3*P3 );
      C2 = C2 + B2*( p(i,:) - B0*P0 - B3*P3 );
      
   end
   
   DENOM=(A1*A2-A12*A12);       % common denominator for all points
   if(DENOM==0)
       P1=P0;
       P2=P3;
   else
       P1=(A2*C1-A12*C2)/DENOM;
       P2=(A1*C2-A12*C1)/DENOM;
   end
   
end            % END of if-elseif-else conditon

if(nargout==5) % if number of output argument=1 
    tout=t;
end

% % % --------------------------------
% % % Author: Dr. Murtaza Khan
% % % Email : drkhanmurtaza@gmail.com
% % % --------------------------------

Contact us at files@mathworks.com