Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
equally spaced data points over a curve

Subject: equally spaced data points over a curve

From: Dave Brackett

Date: 10 Nov, 2008 14:15:04

Message: 1 of 5

Hi,

I have plotted a curve which connects up some data points. The curve is not a straight line.

I would like to compute a new set of data points from the plotted curve, but equally spaced over the length of the curve. The number of points would be specified which would control the resolution.

Does anyone know how I could do this? If you need any more information please ask. Thanks.

Subject: equally spaced data points over a curve

From: Doug Schwarz

Date: 10 Nov, 2008 16:37:19

Message: 2 of 5

In article <gf9fl8$4kh$1@fred.mathworks.com>,
 "Dave Brackett" <davebrackett@hotmail.com> wrote:

> Hi,
>
> I have plotted a curve which connects up some data points. The curve is not a
> straight line.
>
> I would like to compute a new set of data points from the plotted curve, but
> equally spaced over the length of the curve. The number of points would be
> specified which would control the resolution.
>
> Does anyone know how I could do this? If you need any more information please
> ask. Thanks.

Here's something I plan on contributing to the FEX when I get a chance
to clean it up and document it. It's not especially fast, but if you
already have x and y in functional form it could be faster.


----------------- linspacearc.m ---------------------------
function [x2,y2] = linspacearc(x,y,n)
m = length(x);
t = linspace(0,1,m);
ppx = spline(t,x);
ppy = spline(t,y);
 
dppx = pp_deriv(ppx);
dppy = pp_deriv(ppy);
integrand = @(tt) sqrt(ppval(dppx,tt).^2 + ppval(dppy,tt).^2);
arc_length = quadgk(integrand,0,1);
s = linspace(0,arc_length,n);
 
inv_arc_len = @(arc,est) fzero(@(u)(quadgk(integrand,0,u)) - arc,est);
 
t2 = zeros(1,n);
t2(1) = inv_arc_len(s(1),0);
for i = 2:n
    t2(i) = inv_arc_len(s(i),t2(i-1));
end
 
x2 = ppval(ppx,t2);
y2 = ppval(ppy,t2);
 
 
function dpp = pp_deriv(pp)
% pp_deriv: derivative of piecewise polynomial (pp)
 
dpp = pp;
n = pp.order;
dpp.coefs = bsxfun(@times,n-1:-1:1,pp.coefs(:,1:n-1));
dpp.order = n - 1;
-------------------------------------------------------------


Simply pass in your x and y vectors and the number of desired output
points and get back your new x and y vectors.

--
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.

Subject: equally spaced data points over a curve

From: Dave Brackett

Date: 10 Nov, 2008 18:02:03

Message: 3 of 5

Thanks for your code Doug, however, it doesn't do what I want. Your code computes points over the curve equally spaced along the x axis. What I want is to compute points over the curve equally spaced along the curve.

My curve has regions of zero gradient and regions of much steeper gradient. I want the distance between each set of two points to be the same over the length of the curve.

Do you know how your code could be edited to enable this? Thanks for your help so far.




Doug Schwarz <see@sig.for.address.edu> wrote in message <see-AE3628.11371810112008@news.frontiernet.net>...
> In article <gf9fl8$4kh$1@fred.mathworks.com>,
> "Dave Brackett" <davebrackett@hotmail.com> wrote:
>
> > Hi,
> >
> > I have plotted a curve which connects up some data points. The curve is not a
> > straight line.
> >
> > I would like to compute a new set of data points from the plotted curve, but
> > equally spaced over the length of the curve. The number of points would be
> > specified which would control the resolution.
> >
> > Does anyone know how I could do this? If you need any more information please
> > ask. Thanks.
>
> Here's something I plan on contributing to the FEX when I get a chance
> to clean it up and document it. It's not especially fast, but if you
> already have x and y in functional form it could be faster.
>
>
> ----------------- linspacearc.m ---------------------------
> function [x2,y2] = linspacearc(x,y,n)
> m = length(x);
> t = linspace(0,1,m);
> ppx = spline(t,x);
> ppy = spline(t,y);
>
> dppx = pp_deriv(ppx);
> dppy = pp_deriv(ppy);
> integrand = @(tt) sqrt(ppval(dppx,tt).^2 + ppval(dppy,tt).^2);
> arc_length = quadgk(integrand,0,1);
> s = linspace(0,arc_length,n);
>
> inv_arc_len = @(arc,est) fzero(@(u)(quadgk(integrand,0,u)) - arc,est);
>
> t2 = zeros(1,n);
> t2(1) = inv_arc_len(s(1),0);
> for i = 2:n
> t2(i) = inv_arc_len(s(i),t2(i-1));
> end
>
> x2 = ppval(ppx,t2);
> y2 = ppval(ppy,t2);
>
>
> function dpp = pp_deriv(pp)
> % pp_deriv: derivative of piecewise polynomial (pp)
>
> dpp = pp;
> n = pp.order;
> dpp.coefs = bsxfun(@times,n-1:-1:1,pp.coefs(:,1:n-1));
> dpp.order = n - 1;
> -------------------------------------------------------------
>
>
> Simply pass in your x and y vectors and the number of desired output
> points and get back your new x and y vectors.
>
> --
> Doug Schwarz
> dmschwarz&ieee,org
> Make obvious changes to get real email address.

Subject: equally spaced data points over a curve

From: Doug Schwarz

Date: 10 Nov, 2008 18:38:30

Message: 4 of 5

[top posting repaired]

In article <gf9sur$r89$1@fred.mathworks.com>,
 "Dave Brackett" <davebrackett@hotmail.com> wrote:

> Doug Schwarz <see@sig.for.address.edu> wrote in message
> <see-AE3628.11371810112008@news.frontiernet.net>...
> > In article <gf9fl8$4kh$1@fred.mathworks.com>,
> > "Dave Brackett" <davebrackett@hotmail.com> wrote:
> >
> > > Hi,
> > >
> > > I have plotted a curve which connects up some data points. The curve is
> > > not a
> > > straight line.
> > >
> > > I would like to compute a new set of data points from the plotted curve,
> > > but
> > > equally spaced over the length of the curve. The number of points would
> > > be
> > > specified which would control the resolution.
> > >
> > > Does anyone know how I could do this? If you need any more information
> > > please
> > > ask. Thanks.
> >
> > Here's something I plan on contributing to the FEX when I get a chance
> > to clean it up and document it. It's not especially fast, but if you
> > already have x and y in functional form it could be faster.
> >
> >
> > ----------------- linspacearc.m ---------------------------
> > function [x2,y2] = linspacearc(x,y,n)
> > m = length(x);
> > t = linspace(0,1,m);
> > ppx = spline(t,x);
> > ppy = spline(t,y);
> >
> > dppx = pp_deriv(ppx);
> > dppy = pp_deriv(ppy);
> > integrand = @(tt) sqrt(ppval(dppx,tt).^2 + ppval(dppy,tt).^2);
> > arc_length = quadgk(integrand,0,1);
> > s = linspace(0,arc_length,n);
> >
> > inv_arc_len = @(arc,est) fzero(@(u)(quadgk(integrand,0,u)) - arc,est);
> >
> > t2 = zeros(1,n);
> > t2(1) = inv_arc_len(s(1),0);
> > for i = 2:n
> > t2(i) = inv_arc_len(s(i),t2(i-1));
> > end
> >
> > x2 = ppval(ppx,t2);
> > y2 = ppval(ppy,t2);
> >
> >
> > function dpp = pp_deriv(pp)
> > % pp_deriv: derivative of piecewise polynomial (pp)
> >
> > dpp = pp;
> > n = pp.order;
> > dpp.coefs = bsxfun(@times,n-1:-1:1,pp.coefs(:,1:n-1));
> > dpp.order = n - 1;
> > -------------------------------------------------------------
> >
> >
> > Simply pass in your x and y vectors and the number of desired output
> > points and get back your new x and y vectors.
>
>
> Thanks for your code Doug, however, it doesn't do what I want. Your code
> computes points over the curve equally spaced along the x axis. What I want
> is to compute points over the curve equally spaced along the curve.
>
> My curve has regions of zero gradient and regions of much steeper gradient. I
> want the distance between each set of two points to be the same over the
> length of the curve.
>
> Do you know how your code could be edited to enable this? Thanks for your
> help so far.


No, it does exactly what you asked for, but it is possible that your
specific data tricks it up somehow or makes this not obvious. In
particular, it is quite easy to be fooled if you are judging this
visually and you haven't set the axes to have equal scaling in the X and
Y directions (use "axis equal"). If you can't seem to get it to work
please post or send me as small an example as possible and I would be
glad to take a look at it.

--
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.

Subject: equally spaced data points over a curve

From: Dave Brackett

Date: 10 Nov, 2008 22:53:02

Message: 5 of 5

Doug Schwarz <see@sig.for.address.edu> wrote in message <see-1B4CC7.13383010112008@news.frontiernet.net>...
> [top posting repaired]
>
> In article <gf9sur$r89$1@fred.mathworks.com>,
> "Dave Brackett" <davebrackett@hotmail.com> wrote:
>
> > Doug Schwarz <see@sig.for.address.edu> wrote in message
> > <see-AE3628.11371810112008@news.frontiernet.net>...
> > > In article <gf9fl8$4kh$1@fred.mathworks.com>,
> > > "Dave Brackett" <davebrackett@hotmail.com> wrote:
> > >
> > > > Hi,
> > > >
> > > > I have plotted a curve which connects up some data points. The curve is
> > > > not a
> > > > straight line.
> > > >
> > > > I would like to compute a new set of data points from the plotted curve,
> > > > but
> > > > equally spaced over the length of the curve. The number of points would
> > > > be
> > > > specified which would control the resolution.
> > > >
> > > > Does anyone know how I could do this? If you need any more information
> > > > please
> > > > ask. Thanks.
> > >
> > > Here's something I plan on contributing to the FEX when I get a chance
> > > to clean it up and document it. It's not especially fast, but if you
> > > already have x and y in functional form it could be faster.
> > >
> > >
> > > ----------------- linspacearc.m ---------------------------
> > > function [x2,y2] = linspacearc(x,y,n)
> > > m = length(x);
> > > t = linspace(0,1,m);
> > > ppx = spline(t,x);
> > > ppy = spline(t,y);
> > >
> > > dppx = pp_deriv(ppx);
> > > dppy = pp_deriv(ppy);
> > > integrand = @(tt) sqrt(ppval(dppx,tt).^2 + ppval(dppy,tt).^2);
> > > arc_length = quadgk(integrand,0,1);
> > > s = linspace(0,arc_length,n);
> > >
> > > inv_arc_len = @(arc,est) fzero(@(u)(quadgk(integrand,0,u)) - arc,est);
> > >
> > > t2 = zeros(1,n);
> > > t2(1) = inv_arc_len(s(1),0);
> > > for i = 2:n
> > > t2(i) = inv_arc_len(s(i),t2(i-1));
> > > end
> > >
> > > x2 = ppval(ppx,t2);
> > > y2 = ppval(ppy,t2);
> > >
> > >
> > > function dpp = pp_deriv(pp)
> > > % pp_deriv: derivative of piecewise polynomial (pp)
> > >
> > > dpp = pp;
> > > n = pp.order;
> > > dpp.coefs = bsxfun(@times,n-1:-1:1,pp.coefs(:,1:n-1));
> > > dpp.order = n - 1;
> > > -------------------------------------------------------------
> > >
> > >
> > > Simply pass in your x and y vectors and the number of desired output
> > > points and get back your new x and y vectors.
> >
> >
> > Thanks for your code Doug, however, it doesn't do what I want. Your code
> > computes points over the curve equally spaced along the x axis. What I want
> > is to compute points over the curve equally spaced along the curve.
> >
> > My curve has regions of zero gradient and regions of much steeper gradient. I
> > want the distance between each set of two points to be the same over the
> > length of the curve.
> >
> > Do you know how your code could be edited to enable this? Thanks for your
> > help so far.
>
>
> No, it does exactly what you asked for, but it is possible that your
> specific data tricks it up somehow or makes this not obvious. In
> particular, it is quite easy to be fooled if you are judging this
> visually and you haven't set the axes to have equal scaling in the X and
> Y directions (use "axis equal"). If you can't seem to get it to work
> please post or send me as small an example as possible and I would be
> glad to take a look at it.
>
> --
> Doug Schwarz
> dmschwarz&ieee,org
> Make obvious changes to get real email address.

Ah yes, you are right, sorry about that - i didn't have my axes equally scaled. once I set that the code works fine. thanks a lot for your help.

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us