Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.postscript > #2753 > unrolled thread

a smooth curve through given points ?

Started byPeter Billam <peter@www.pjb.com.au>
First post2016-08-12 08:10 +0000
Last post2016-11-05 10:12 -0700
Articles 20 on this page of 29 — 9 participants

Back to article view | Back to comp.lang.postscript


Contents

  a smooth curve through given points ? Peter Billam <peter@www.pjb.com.au> - 2016-08-12 08:10 +0000
    Re: a smooth curve through given points ? Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-08-12 01:12 -0700
    Re: a smooth curve through given points ? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2016-08-12 21:59 -0400
      Re: a smooth curve through given points ? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2016-08-13 22:42 -0400
    Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-12 21:49 -0700
      Re: a smooth curve through given points ? Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-08-12 21:59 -0700
        Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-12 22:21 -0700
        Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-18 15:01 -0700
          Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-19 13:10 -0700
            Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-19 13:13 -0700
      Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-12 22:00 -0700
      Re: a smooth curve through given points ? Peter Billam <peter@www.pjb.com.au> - 2016-08-13 09:44 +0000
        Re: a smooth curve through given points ? Peter Billam <peter@www.pjb.com.au> - 2016-08-15 01:00 +0000
          Re: a smooth curve through given points ? John Forkosh <forkosh@panix.com> - 2016-08-15 03:08 +0000
            Re: a smooth curve through given points ? Peter Billam <peter@www.pjb.com.au> - 2016-08-15 09:36 +0000
              Re: a smooth curve through given points ? JohnF <john@please.see.sig.for.email.com> - 2016-08-16 01:28 +0000
                Re: a smooth curve through given points ? Peter Billam <peter@www.pjb.com.au> - 2016-08-16 23:32 +0000
                  Re: a smooth curve through given points ? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2016-08-17 01:07 -0400
      Re: a smooth curve through given points ? JohnF <john@please.see.sig.for.email.com> - 2016-08-14 06:17 +0000
    Re: a smooth curve through given points ? jdaw1 <jdawiseman@gmail.com> - 2016-08-16 03:14 -0700
    Re: a smooth curve through given points ? Alan <alan.isaac@gmail.com> - 2016-08-18 14:42 -0700
      Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-18 15:19 -0700
        Re: a smooth curve through given points ? Alan <alan.isaac@gmail.com> - 2016-08-18 18:52 -0700
          Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-18 21:47 -0700
            Re: a smooth curve through given points ? Alan <alan.isaac@gmail.com> - 2016-08-19 06:01 -0700
              Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-08-19 14:06 -0700
    Re: a smooth curve through given points ? luser droog <luser.droog@gmail.com> - 2016-11-03 22:03 -0700
      Re: a smooth curve through given points ? JohnF <john@please.see.sig.for.email.com> - 2016-11-05 05:19 +0000
      Re: a smooth curve through given points ? don lancaster <don@tinaja.com> - 2016-11-05 10:12 -0700

Page 1 of 2  [1] 2  Next page →


#2753 — a smooth curve through given points ?

FromPeter Billam <peter@www.pjb.com.au>
Date2016-08-12 08:10 +0000
Subjecta smooth curve through given points ?
Message-ID<slrnnqr130.4f6.peter@box8.pjb.com.au>
Hi.  There must be reasonable ways of constructing a series
of curveto's that go smoothly through a given array of points
[x1 y1 x2 y2 ... xN yN] ...  Anyone here written stuff like that,
or know of where it could be found ?

If I do it, it'll turn out very ad-hoc and heuristic-ish,
with lots of arrays-of-points that cause wild behaviour :-(

Thanks,
Regards,
Peter

-- 

Peter Billam    www.pjb.com.au    www.pjb.com.au/comp/contact.html

[toc] | [next] | [standalone]


#2754

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-08-12 01:12 -0700
Message-ID<c1075b7d-b331-4659-8712-1977d2b1ad2f@googlegroups.com>
In reply to#2753
On Friday, August 12, 2016 at 8:10:09 PM UTC+12, Peter Billam wrote:
> There must be reasonable ways of constructing a series
> of curveto's that go smoothly through a given array of points
> [x1 y1 x2 y2 ... xN yN] ... 

All the reasons I can think of for wanting such a thing smack of ... social science ...

[toc] | [prev] | [next] | [standalone]


#2762

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2016-08-12 21:59 -0400
Message-ID<1u34trn8nyv0p$.1gvzyj8xl99a9$.dlg@40tude.net>
In reply to#2753
On 12 Aug 2016 08:10:08 GMT, Peter Billam wrote:

> Hi.  There must be reasonable ways of constructing a series
> of curveto's that go smoothly through a given array of points
> [x1 y1 x2 y2 ... xN yN] ...  Anyone here written stuff like that,
> or know of where it could be found ?

I can only give you my glib "mathematical cocktail party" remarks about
that, viz., that just as there's a single linear (straight-line) "curveto"
from one point to another, a single quadratic parametrized curve from one
point through a second to a third, a single cubically parametrized curve
through four points [x0 y0 x1 y1 x2 y2 x3 y3] (the usual Bezier "curveto"
of PostScript), etc., so there's a single curve, parametrized by a pair of
polynomials of degree N, passing through an array of N+1 points [x0 y0 x1
y1 x2 y2 ... xN yN] in the fashion you describe.

As for the algorithmics of that result, it can be done with matrix algebra,
but I'd hate to have to implement it myself: I'm more the theoretical sort
who's content to know of an existence proof, even if it's non-constructive.
 
From a completely different tack, though, one might try instead to use
spline-type mixings of the "curveto" figures for the various foursomes
[x0 y0 x1 y1 x2 y2 x3 y3] ,... on up (for N > 3) through 
[x(N-3) y(N-3) x(N-2) y(N-2) x(N-1) y(N-1) xN yN] .

HTH. Cheers, -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#2769

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2016-08-13 22:42 -0400
Message-ID<a6cyjwxm2zo0$.wnhssn52i31g$.dlg@40tude.net>
In reply to#2762
On Fri, 12 Aug 2016 21:59:21 -0400, tlvp wrote (erroneously):

> ... a single cubically parametrized curve
> through four points [x0 y0 x1 y1 x2 y2 x3 y3] (the usual Bezier "curveto"
> of PostScript), ...

The errror is not in the assertion that there is indeed a single cubically
parametrized curve through four points, as stated above, the error rather
is in the parenthetical remark that that curve is "the usual Bezier
"curveto" of PostScript". It is not -- as luser droog's remark 3 hours
after mine makes plain -- the curveto in question, while it does pass
through the first point and the last, does not generally *pass through* the
intermediate two points, but rather is "controlled by" them.

Apologies for my hastily scribbled gaffe. Cheers, -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#2763

Fromluser droog <luser.droog@gmail.com>
Date2016-08-12 21:49 -0700
Message-ID<3243f726-6885-4ae2-aac9-f8834261dc73@googlegroups.com>
In reply to#2753
On Friday, August 12, 2016 at 3:10:09 AM UTC-5, Peter Billam wrote:
> Hi.  There must be reasonable ways of constructing a series
> of curveto's that go smoothly through a given array of points
> [x1 y1 x2 y2 ... xN yN] ...  Anyone here written stuff like that,
> or know of where it could be found ?
> 
> If I do it, it'll turn out very ad-hoc and heuristic-ish,
> with lots of arrays-of-points that cause wild behaviour :-(
> 

Somewhat on the same level as tlvp's thoughts, I have a few 
observations about Bezier curves. Everybody probably knows
these things already, but perhaps I can describe them in a
novel way.

A cubic Bezier curve in 2D is determined by 4 coordinate pairs,
x1 y1, x2 y2, x3 y3, x4 y4, and passes through points 1 and 4.
The vectors from the interior points to their adjacent outer
points determine the tangents as the curve passes through those
same outer points.

In ascii-art,

      .      .
 .    p2     p3    .
 p1                p4

The trace of the curve from t=0 to t=1 starts at p1, then moves 
toward p2, along the vector p2-p1. As the curve progresses, the
weight associated with the p2-p1 tangent vector goes from 1 to 0.
At the same time the weight associated with the p4-p3 tangent
vector goes from 0 to 1. So the instant the curve crosses the
finish t=1, it is wholly under the control of the exiting tangent
vector p4-p3.

Now with some calculus background, we learn that tangents in general
can be found by taking the derivative of a function. The first 
derivative, evaluated at a specific value for t, gives the "slope"
at the corresponding point of the original function for the same t 
value. The second derivative gives the "curvature" or acceleration,
how much the slope is changing.

The practical upshot (and skipping a few steps) is, to smoothly 
connect two Bezier curves at a join, first the inner control
points adjacent to the join point need to be collinear. This gives
gives you matching slopes as the curve crosses the join.

      .      .
 .    p2     p3    .                 .
 p1                p4    .     .     p7
                         p5    p6

<p3, p4, p5> need to be collinear.

To match curvature, the magnitudes of the adjacent tangent vectors
need to be the same (or not too different).

|p4-p3| ~= |p5-p4|

So what remains is the "outer" inner control points, p2 and p6.
With no rigor at all, my guess is they should be collinear with
their adjacent control points.

So, not an algorithm. But maybe this can help someone else come
up with something.

[toc] | [prev] | [next] | [standalone]


#2764

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-08-12 21:59 -0700
Message-ID<43b25acc-671b-4f81-9a5a-3ed5e5813985@googlegroups.com>
In reply to#2763
On Saturday, August 13, 2016 at 4:49:47 PM UTC+12, luser droog wrote:
> With no rigor at all, my guess is they should be collinear with
> their adjacent control points.

successive on-curve-off-curve-off-curve points which are collinear will give you a straight line.

[toc] | [prev] | [next] | [standalone]


#2766

Fromluser droog <luser.droog@gmail.com>
Date2016-08-12 22:21 -0700
Message-ID<e9c2b374-6e12-4620-bef3-ee846d8926c0@googlegroups.com>
In reply to#2764
On Friday, August 12, 2016 at 11:59:40 PM UTC-5, Lawrence D’Oliveiro wrote:
> On Saturday, August 13, 2016 at 4:49:47 PM UTC+12, luser droog wrote:
> > With no rigor at all, my guess is they should be collinear with
> > their adjacent control points.
> 
> successive on-curve-off-curve-off-curve points which are collinear will give you a straight line.

I didn't mean for everything to be collinear. Although that could happen
with my scheme if the data are in fact collinear.

I was imagining something like this: you start with 3 points and want
to make 2 curves passing through them. Using the same convention from
my previous post, the 3 given points are p1, p4, and p7. 

Suppose the 3 points are not collinear.

              .
  .           p4
  p1                     .
                         p7

An initial selection for p3 and p5 might be on lines from p1 to p4 
and from p4 to p7, giving

           .  .
  .        p3 p4  .
  p1              p5     .
                         p7

But they then need to be tweaked to meet the collinearity criterion.

           .  .    .
  .        p3 p4   p5
  p1                     .
                         p7

And again to balance magnitudes.

          .    .    .
  .       p3   p4   p5
  p1                     .
                         p7

Then if p2 and p6 are chosen in the natural manner,


      .   .    .    .
  .   p2  p3   p4   p5 .
  p1                  p6 .
                         p7

That should give a nice result when the details are filled in.

[toc] | [prev] | [next] | [standalone]


#2781

Fromluser droog <luser.droog@gmail.com>
Date2016-08-18 15:01 -0700
Message-ID<1a3d95c0-e58b-4dde-ab78-7e0d1b4a290d@googlegroups.com>
In reply to#2764
On Friday, August 12, 2016 at 11:59:40 PM UTC-5, Lawrence D’Oliveiro wrote:
> On Saturday, August 13, 2016 at 4:49:47 PM UTC+12, luser droog wrote:
> > With no rigor at all, my guess is they should be collinear with
> > their adjacent control points.
> 
> successive on-curve-off-curve-off-curve points which are collinear will give you a straight line.

Confirmed. I've been leisurely pursuing this idea since the OP,
and partly implemented my idea. But I have not written the middle
"refining" step where it enforces colinearity and balances the 
magnitudes. But as predicted, with the "hard example" posted elsethread,
the output is a (jagged) straight line.

It's also written very bottom-up, even wasting lots of time to
make sure that `exit` works in my loop functions.

uses mat.ps
https://github.com/luser-dr00g/xpost/blob/master/data/mat.ps

GPL Ghostscript 9.15 (2014-09-22)
Copyright (C) 2014 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>
Press ENTER or type command to continue
GPL Ghostscript 9.15 (2014-09-22)
Copyright (C) 2014 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
250 300
247.5 325.0
245.0 350.0
240 400
250.0 395.0
250.0 395.0
260 390
255.0 495.0
252.5 547.5
250 600
GS>
Press ENTER or type command to continue

josh@LAPTOP-ILO10OOF ~
$ cat smooth.ps 
% proc  .  -
/endexecbegin {
    [ exch /exec cvx currentdict /begin cvx ]
    end cvx exec
} def

% array n proc  .  -
/fortuple { 3 dict begin
    0 {offset proc n arr} {exch def} forall
    /arr load length n idiv
    {
        {
            /arr load offset n getinterval
            /proc load endexecbegin
            /offset offset n add def
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if
    } repeat
end
} def

%[ 0 1 10 {} for ] 3 {} fortuple pstack clear ()=

% array n proc  .  -
/fortups { 3 dict begin
    {proc n arr} {exch def} forall
    0 1 /arr load length n sub { /offset exch def
        {
            /arr load offset n getinterval
            /proc load endexecbegin
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if
    } for
end } def

%[ 0 1 10 {} for ] 3 {} fortups pstack clear ()=

% array     n bool proc  .  -
% array ini n bool proc  .  -
/fort { 5 dict begin
    /proc exch def
    /tail exch def
    /n exch def
    dup type /integertype eq { /ini exch def } if
    /arr exch def
    {

        {
            currentdict /ini known {
                /arr load 0 ini getinterval
                /proc load endexecbegin
                /offset ini def
            }{
                /offset 0 def
            } ifelse
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if

        {
            /arr load length offset sub n idiv
            {
                {
                    /arr load offset n getinterval
                    /proc load endexecbegin
                    /offset offset n add def
                } stopped {
                    $error/errorname get/invalidexit eq
                    { 1 dict begin
                        $error/newerror false put
                        stop }{ stop } ifelse
                } if
            } repeat
        } stopped {
            $error/newerror get not { exit } if
        } if

        {
            currentdict /tail known { tail {
                offset /arr load length 1 sub le {
                    /arr load offset 1 index length offset sub getinterval
                    /proc load endexecbegin
                } if
            } if } if
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if

    exit } loop

end } def

%/i 0 def
%[ 0 1 10 {} for ] 1 3 true {i 4 eq{exit}if /i i 1 add def 12 } fort

(mat.ps)run
/median {{add 2 div} vop} def

/interpolate
    { % [p0 p1 p2]
        aload pop 1 index % p0 p1 p2 p1
        median % p0 p1 p12
        3 1 roll % p12 p0 p1
        exch 1 index % p12 p1 p0 p1
        median % p12 p1 p01
        exch 3 2 roll % p01 p1 p12
    }
def

% array  .  -
/smooth { 5 dict begin
    {arr} {exch def} forall
    /pts [ /arr load 2 {} fortuple ] def

    /pts [
    pts 0 get
    pts 3 //interpolate fortups
    pts dup length 1 sub get
    ] def

    /pts [
        pts aload pop
        pts 0 2 getinterval aload pop median % [ p t s p01
        counttomark 1 sub 1 roll % [ p p01 t s
        2 copy median % [ p p01 t s pn-2,n-1
        exch % [ p p01 t pn-2,n-1 s
    ] def

    pts 1 3 false {
        {{}{aload pop aload pop 2 copy exch =only( )print = moveto}
         {}{{aload pop 2 copy exch =only( )print =}forall curveto}} 1 index length get exec
    } fort
        
end } def

[250 300  240 400  260 390  250 600] smooth stroke

[toc] | [prev] | [next] | [standalone]


#2786

Fromluser droog <luser.droog@gmail.com>
Date2016-08-19 13:10 -0700
Message-ID<2f24ddc1-758b-4159-a14f-d83ea18ece21@googlegroups.com>
In reply to#2781
On Thursday, August 18, 2016 at 5:01:30 PM UTC-5, luser droog wrote:
> On Friday, August 12, 2016 at 11:59:40 PM UTC-5, Lawrence D’Oliveiro wrote:
> > On Saturday, August 13, 2016 at 4:49:47 PM UTC+12, luser droog wrote:
> > > With no rigor at all, my guess is they should be collinear with
> > > their adjacent control points.
> > 
> > successive on-curve-off-curve-off-curve points which are collinear will give you a straight line.
> 
> Confirmed. I've been leisurely pursuing this idea since the OP,
> and partly implemented my idea. But I have not written the middle
> "refining" step where it enforces colinearity and balances the 
> magnitudes. But as predicted, with the "hard example" posted elsethread,
> the output is a (jagged) straight line.
> 
> It's also written very bottom-up, even wasting lots of time to
> make sure that `exit` works in my loop functions.
> 
> uses mat.ps
> https://github.com/luser-dr00g/xpost/blob/master/data/mat.ps
> 

Got it to do something. For the perverse input, it finds a nice
curve on the second iteration but then gets into a knot.

And some comments on what those crazy functions do (sorry about 
omitting that earlier).


josh@LAPTOP-ILO10OOF ~
$ cat smooth.ps 
% proc  .  -
/endexecbegin {
    [ exch /exec cvx currentdict /begin cvx ]
    end cvx exec
} def

% array n proc  .  -
% Like `forall` but delivers length=5 subsequences produced by getinterval
/fortuple { 3 dict begin
    0 {offset proc n arr} {exch def} forall
    /arr load length n idiv
    {
        {
            /arr load offset n getinterval
            /proc load endexecbegin
            /offset offset n add def
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if
    } repeat
end
} def

%[ 0 1 10 {} for ] 3 {} fortuple pstack clear ()=

% array n proc  .  -
% Like `fortuple` but delivers overlapping slices, 
% incrementing the offset by 1 each time
/fortups { 3 dict begin
    {proc n arr} {exch def} forall
    0 1 /arr load length n sub { /offset exch def
        {
            /arr load offset n getinterval
            /proc load endexecbegin
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if
    } for
end } def

%[ 0 1 10 {} for ] 3 {} fortups pstack clear ()=

% array     n bool proc  .  -
% array ini n bool proc  .  -
% Like `fortuple` but bool controls whether to call proc
% on the "tail" if there's a final sequence of length <n .
% Can optionally specify an "ini" sequence length before
% it begins taking n-length sequences.
%
/fort { 5 dict begin
    /proc exch def
    /tail exch def
    /n exch def
    dup type /integertype eq { /ini exch def } if
    /arr exch def
    {

        {
            currentdict /ini known {
                /arr load 0 ini getinterval
                /proc load endexecbegin
                /offset ini def
            }{
                /offset 0 def
            } ifelse
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if

        {
            /arr load length offset sub n idiv
            {
                {
                    /arr load offset n getinterval
                    /proc load endexecbegin
                    /offset offset n add def
                } stopped {
                    $error/errorname get/invalidexit eq
                    { 1 dict begin
                        $error/newerror false put
                        stop }{ stop } ifelse
                } if
            } repeat
        } stopped {
            $error/newerror get not { exit }{ stop } ifelse
        } if

        {
            currentdict /tail known { tail {
                offset /arr load length 1 sub le {
                    /arr load offset 1 index length offset sub getinterval
                    /proc load endexecbegin
                } if
            } if } if
        } stopped {
            $error/errorname get/invalidexit eq
            { 1 dict begin exit }{ stop } ifelse
        } if

    exit } loop

end } def

%/i 0 def
%[ 0 1 10 {} for ] 1 3 true {i 4 eq{exit}if /i i 1 add def 12 } fort

(mat.ps)run % load matrix library
/median { %pstack()=
    {add 2 div} vop} def  % vop, "vector op" applies proc to corresponding
                          % elements of 2 vectors producing a vector result

/interpolate
    { % [p0 p1 p2]
        aload pop 1 index % p0 p1 p2 p1
        median % p0 p1 p12
        3 1 roll % p12 p0 p1
        exch 1 index % p12 p1 p0 p1
        median % p12 p1 p01
        exch 3 2 roll % p01 p1 p12
    }
def

/refine
    { % [p0 p1 p2]
        aload pop {p2 p1 p0} {exch def} forall
        /v1 p1 p0 {sub} vop def
        /v2 p2 p1 {sub} vop def
        /v3 v1 v2 {add 2 div} vop def
        /a1 v1 aload pop exch 0.001 add atan def
        /a2 v2 aload pop exch 0.001 add atan def
        /a3 v3 aload pop exch 0.001 add atan def
        /r1 0 v1 {dup mul add} forall sqrt def
        /r2 0 v2 {dup mul add} forall sqrt def
        /r3 0 v3 {dup mul add} forall sqrt def

        /da a2 a1 sub def
        /aa a3 def %a1 da 2 div add def
        /da1 aa a1 sub def
        /da2 aa a2 sub def

        /dr r2 r1 sub abs def
        /ar r3 def %r1 r2 add 2 div def
        /dr1 ar r1 sub def
        /dr2 ar r2 sub def

        /a1 a1 da1 steps div add def
        /a2 a2 da2 steps div add def
        /r1 r1 dr1 steps div add def
        /r2 r2 dr2 steps div add def
        
        p1 [r1 a1 cos mul  r1 a1 sin mul] {sub}vop
        p1
        p1 [r2 a2 cos mul  r2 a2 sin mul] {add}vop
    }
def

/getpairs {
    [ exch 2 {} fortuple ]  % fortuple converts coordinate list to pairs
} def

% array steps  .  -
/smooth { 5 dict begin
    {steps arr} {exch def} forall
    /pts /arr load getpairs def

    /pts [
        pts 0 get
        [ pts 3 //interpolate fortups ]  % generate by adding midpoints
        steps { [ exch 3 //refine fortuple ] } repeat  % adjust added points
        aload pop
        pts dup length 1 sub get
    ] def

    /pts [   % add post-initial and pre-final control points
        pts aload pop
        pts 0 2 getinterval aload pop median % [ p t s p01
        counttomark 1 sub 1 roll % [ p p01 t s
        2 copy median % [ p p01 t s pn-2,n-1
        exch % [ p p01 t pn-2,n-1 s
    ] def

    % call with first length=1 sequence ( and `moveto` it)
    % call with triples after that (and `curveto` each)
    pts 1 3 false {
        {{}{aload pop aload pop 2 copy exch =only( )print = moveto}
         {}{{aload pop 2 copy exch =only( )print =}forall curveto}} 1 index length get exec
    } fort
        
end } def

0 1 1000 {
    (steps=)=only dup =
    [250 300  240 400  260 390  250 600] exch smooth stroke
    showpage
} for


josh@LAPTOP-ILO10OOF ~
$ ;

[toc] | [prev] | [next] | [standalone]


#2787

Fromluser droog <luser.droog@gmail.com>
Date2016-08-19 13:13 -0700
Message-ID<3a5f87d5-23f6-4187-807b-62cd2e175353@googlegroups.com>
In reply to#2786
On Friday, August 19, 2016 at 3:10:27 PM UTC-5, luser droog wrote:

> % array n proc  .  -
> % Like `forall` but delivers length=5 subsequences produced by getinterval
> /fortuple { 3 dict begin

s.b. length=n

-- 
acai

[toc] | [prev] | [next] | [standalone]


#2765

Fromluser droog <luser.droog@gmail.com>
Date2016-08-12 22:00 -0700
Message-ID<34e4175c-3be3-4948-a681-7fbbc4bb2886@googlegroups.com>
In reply to#2763
On Friday, August 12, 2016 at 11:49:47 PM UTC-5, luser droog wrote:
> On Friday, August 12, 2016 at 3:10:09 AM UTC-5, Peter Billam wrote:
> > Hi.  There must be reasonable ways of constructing a series
> > of curveto's that go smoothly through a given array of points
> > [x1 y1 x2 y2 ... xN yN] ...  Anyone here written stuff like that,
> > or know of where it could be found ?
> > 
> > If I do it, it'll turn out very ad-hoc and heuristic-ish,
> > with lots of arrays-of-points that cause wild behaviour :-(
> > 
> 
> Somewhat on the same level as tlvp's thoughts, I have a few 
> observations about Bezier curves. Everybody probably knows
> these things already, but perhaps I can describe them in a
> novel way.
> 
> A cubic Bezier curve in 2D is determined by 4 coordinate pairs,
> x1 y1, x2 y2, x3 y3, x4 y4, and passes through points 1 and 4.
> The vectors from the interior points to their adjacent outer
> points determine the tangents as the curve passes through those
> same outer points.

It might unlock more literature to know that the Bezier 
representation of a cubic curve is readily interconvertable
with the Hermite representation which instead of 4 points,
is specified by 2 points and 2 vectors (!). The same tangent
vectors we've been talking about. So if you find something
for Hermite curves, it can be used with a little extra work.

[toc] | [prev] | [next] | [standalone]


#2767

FromPeter Billam <peter@www.pjb.com.au>
Date2016-08-13 09:44 +0000
Message-ID<slrnnqtqv6.48s.peter@box8.pjb.com.au>
In reply to#2763
On 2016-08-13, luser droog <luser.droog@gmail.com> wrote:
> On Friday, August 12, 2016 at 3:10:09 AM UTC-5, Peter Billam wrote:
>> Hi.  There must be reasonable ways of constructing a series
>> of curveto's that go smoothly through a given array of points
>> [x1 y1 x2 y2 ... xN yN] ...  Anyone here written stuff like that,
>> or know of where it could be found ?
>> If I do it, it'll turn out very ad-hoc and heuristic-ish,
>> with lots of arrays-of-points that cause wild behaviour :-(
>
> Somewhat on the same level as tlvp's thoughts,

You're all thinking about exactly the kind of succession of
curveto's that I was thinking about.

> A cubic Bezier curve in 2D is determined by 4 coordinate pairs,
> x1 y1, x2 y2, x3 y3, x4 y4, and passes through points 1 and 4.
> The vectors from the interior points to their adjacent outer
> points determine the tangents as the curve passes through those
> same outer points.
> ...
> In ascii-art,

Nice ascii-art :-)

> At the same time the weight associated with the p4-p3 tangent
> vector goes from 0 to 1. So the instant the curve crosses the
> finish t=1, it is wholly under the control of the exiting tangent
> vector p4-p3.
> ...
> <p3, p4, p5> need to be collinear.

Yes, that's important. Possibly the <p3, p4, p5> gradient should
be at right-angles to the line bisecting the p1-p4-p7 angle?

> To match curvature, the magnitudes of the adjacent tangent
> vectors need to be the same (or not too different).

Matching curvature is not as important as matching gradient, and
I think if p1-to-p4 is a long segment and p4-to-p7 is a short one,
then it probably looks better if p3-to-p4 is reasonable in the
p1-to-p4 context, and p4-to-p5 reasonable in its p4-to-p7 context.
Needs trying out :-)
(Can always take the sqrt of the product of both estimates...)

> So, not an algorithm. But maybe this can help someone else come
> up with something.

OK, I'll give it a go (don't hold your breaths, though).  I'm not
really motivated by plotting smooth graphs, but by drawing curves
for arty stuff, like http://www.pjb.com.au/art/posters/index.html

It should also make it easy to copy a smooth curve from a .jpg or
.png, because you just note the pixel-positions at a few places
along the curve and let the algorithm do the rest. If it's not
right yet, you insert an extra pixel-position into your list...

Thanks,  Peter

-- 

Peter Billam    www.pjb.com.au    www.pjb.com.au/comp/contact.html

[toc] | [prev] | [next] | [standalone]


#2773

FromPeter Billam <peter@www.pjb.com.au>
Date2016-08-15 01:00 +0000
Message-ID<slrnnr250f.1ol.peter@box8.pjb.com.au>
In reply to#2767
On 2016-08-13, Peter Billam <peter@www.pjb.com.au> wrote:
> OK, I'll give it a go (don't hold your breaths, though).  I'm not
> really motivated by plotting smooth graphs, but by drawing curves
> for arty stuff, like http://www.pjb.com.au/art/posters/index.html
> It should also make it easy to copy a smooth curve from a .jpg or
> .png, because you just note the pixel-positions at a few places
> along the curve and let the algorithm do the rest. If it's not
> right yet, you insert an extra pixel-position into your list...

I have a prototype: it can either be called by
  [x1 y1 x2 y2 ... xN yN] points2curve stroke
in which case is makes up its own starting and ending angles,
or by
  [x1 y1 ... xN yN] initialangle finalangle points2curve stroke
if you need to fix the launch- and landing- angles, which you do
eg: for drawing smooth closed curves that join up smoothly.
The plan is to roll it into
  http://www.pjb.com.au/comp/line_drawing.html
which needs a bit of revision anyway...

/xmax currentpagedevice (PageSize) get 0 get def
/ymax currentpagedevice (PageSize) get 1 get def

/points2curve {  % [x1 y1 ... xN yN] initial_angle final_angle points2curve
  % http://stackoverflow.com/questions/7715788/find-bezier-control-points-for-curve-passing-through-n-points
  % http://www.math.ucla.edu/~baker/149.1.02w/handouts/dd_splines.pdf
  % https://corner.squareup.com/2012/07/smoother-signatures.html
  25 dict begin
  /a_top exch def
  a_top type (arraytype) eq { /points a_top def
  } { /final_angle a_top def  /initial_angle exch def /points exch def
  } ifelse
  /p_0_x points 0 get def
  /p_0_y points 1 get def
  p_0_x p_0_y moveto
  /initial_angle where { pop /subangle_m1 initial_angle def } if
  /p_im1_x p_0_x def  /p_im1_y p_0_y def
  2 2 points length 4 sub { /i exch def
    points i       get /p_i_x   exch def
    points i 1 add get /p_i_y   exch def
    points i 2 add get /p_ip1_x exch def
    points i 3 add get /p_ip1_y exch def
    /angle_before  p_i_y p_im1_y sub p_i_x p_im1_x sub atan def
    /angle_after   p_ip1_y p_i_y sub p_ip1_x p_i_x sub atan def
	angle_before 180 gt { /angle_before angle_before 360 sub def } if
	angle_after  180 gt { /angle_after  angle_after  360 sub def } if
    /angle_tangent angle_before angle_after add .5 mul def
    /dist_before
      p_i_y p_im1_y sub dup mul  p_i_x p_im1_x sub dup mul add sqrt def
    /dist_after
      p_i_y p_ip1_y sub dup mul  p_i_x p_ip1_x sub dup mul add sqrt def
    /subangle_m1 where { pop } { /subangle_m1 angle_before def } ifelse
    p_im1_x  subangle_m1 cos dist_before mul 0.40 mul add
    p_im1_y  subangle_m1 sin dist_before mul 0.40 mul add
    p_i_x  angle_tangent cos dist_before mul 0.40 mul sub
    p_i_y  angle_tangent sin dist_before mul 0.40 mul sub
    p_i_x p_i_y curveto
    /p_im1_x p_i_x def  /p_im1_y p_i_y def
    /subangle_m1 angle_tangent def
  } for
  /final_angle where { pop } { /final_angle subangle_m1 def } ifelse
  p_i_x   subangle_m1 cos dist_before mul 0.40 mul add
  p_i_y   subangle_m1 sin dist_before mul 0.40 mul add
  p_ip1_x final_angle cos dist_before mul 0.40 mul sub
  p_ip1_y final_angle sin dist_before mul 0.40 mul sub
  p_ip1_x p_ip1_y curveto   % last point
  end
} def
xmax .002 mul setlinewidth
[ 220 50 100 100 100 200 200 250 300 210 320 100 220 50 ] 170 170
points2curve stroke
[ 400 50 380 100 430 200 360 300 450 400 380 500 410 600 400 700 ] 120 90
points2curve stroke
showpage

Regards,  Peter

-- 

Peter Billam    www.pjb.com.au    www.pjb.com.au/comp/contact.html

[toc] | [prev] | [next] | [standalone]


#2774

FromJohn Forkosh <forkosh@panix.com>
Date2016-08-15 03:08 +0000
Message-ID<norbmp$7mt$1@reader2.panix.com>
In reply to#2773
Peter Billam <peter@www.pjb.com.au> wrote:
> On 2016-08-13, Peter Billam <peter@www.pjb.com.au> wrote:
>> OK, I'll give it a go (don't hold your breaths, though).  I'm not
>> really motivated by plotting smooth graphs, but by drawing curves
>> for arty stuff, like http://www.pjb.com.au/art/posters/index.html
>> It should also make it easy to copy a smooth curve from a .jpg or
>> .png, because you just note the pixel-positions at a few places
>> along the curve and let the algorithm do the rest. If it's not
>> right yet, you insert an extra pixel-position into your list...
> 
> I have a prototype: it can either be called by
>  [x1 y1 x2 y2 ... xN yN] points2curve stroke
> in which case is makes up its own starting and ending angles,
> or by
>  [x1 y1 ... xN yN] initialangle finalangle points2curve stroke
> if you need to fix the launch- and landing- angles, which you do
> eg: for drawing smooth closed curves that join up smoothly.
> The plan is to roll it into
>  http://www.pjb.com.au/comp/line_drawing.html
> which needs a bit of revision anyway...

Peter's code reproduced without leading "> "s
reproduced below

%% ---- cut here ----
/xmax currentpagedevice (PageSize) get 0 get def
/ymax currentpagedevice (PageSize) get 1 get def

/points2curve {  % [x1 y1 ... xN yN] initial_angle final_angle points2curve
 % http://stackoverflow.com/questions/7715788/
 % find-bezier-control-points-for-curve-passing-through-n-points
 % http://www.math.ucla.edu/~baker/149.1.02w/handouts/dd_splines.pdf
 % https://corner.squareup.com/2012/07/smoother-signatures.html
 25 dict begin
 /a_top exch def
 a_top type (arraytype) eq { /points a_top def
 } { /final_angle a_top def  /initial_angle exch def /points exch def
 } ifelse
 /p_0_x points 0 get def
 /p_0_y points 1 get def
 p_0_x p_0_y moveto
 /initial_angle where { pop /subangle_m1 initial_angle def } if
 /p_im1_x p_0_x def  /p_im1_y p_0_y def
 2 2 points length 4 sub { /i exch def
   points i       get /p_i_x   exch def
   points i 1 add get /p_i_y   exch def
   points i 2 add get /p_ip1_x exch def
   points i 3 add get /p_ip1_y exch def
   /angle_before  p_i_y p_im1_y sub p_i_x p_im1_x sub atan def
   /angle_after   p_ip1_y p_i_y sub p_ip1_x p_i_x sub atan def
       angle_before 180 gt { /angle_before angle_before 360 sub def } if
       angle_after  180 gt { /angle_after  angle_after  360 sub def } if
   /angle_tangent angle_before angle_after add .5 mul def
   /dist_before
     p_i_y p_im1_y sub dup mul  p_i_x p_im1_x sub dup mul add sqrt def
   /dist_after
     p_i_y p_ip1_y sub dup mul  p_i_x p_ip1_x sub dup mul add sqrt def
   /subangle_m1 where { pop } { /subangle_m1 angle_before def } ifelse
   p_im1_x  subangle_m1 cos dist_before mul 0.40 mul add
   p_im1_y  subangle_m1 sin dist_before mul 0.40 mul add
   p_i_x  angle_tangent cos dist_before mul 0.40 mul sub
   p_i_y  angle_tangent sin dist_before mul 0.40 mul sub
   p_i_x p_i_y curveto
   /p_im1_x p_i_x def  /p_im1_y p_i_y def
   /subangle_m1 angle_tangent def
 } for
 /final_angle where { pop } { /final_angle subangle_m1 def } ifelse
 p_i_x   subangle_m1 cos dist_before mul 0.40 mul add
 p_i_y   subangle_m1 sin dist_before mul 0.40 mul add
 p_ip1_x final_angle cos dist_before mul 0.40 mul sub
 p_ip1_y final_angle sin dist_before mul 0.40 mul sub
 p_ip1_x p_ip1_y curveto   % last point
 end
} def
xmax .002 mul setlinewidth
[ 220 50 100 100 100 200 200 250 300 210 320 100 220 50 ] 170 170
points2curve stroke
[ 400 50 380 100 430 200 360 300 450 400 380 500 410 600 400 700 ] 120 90
points2curve stroke
showpage
%% ---- cut here ----

> 
> Regards,  Peter

Very nice. I tested it with various other x,y1...x,yn's,
and it seems to behave pretty nicely for the stuff I tested.
Like you, I put together some ps for "arty stuff" (your words
above), and you might find some of that useful. See
  http://www.forkosh.com/images/decorative/decorative13.jpg
for an example. Same_directory/decorative13.ps has all the ps.
And note %comments crediting Gernot Hoffmann -- I don't
know ps well enough to have done it myself (but I did write
the C program that generates the data).
-- 
John Forkosh  ( mailto:  j@f.com  where j=john and f=forkosh )

[toc] | [prev] | [next] | [standalone]


#2775

FromPeter Billam <peter@www.pjb.com.au>
Date2016-08-15 09:36 +0000
Message-ID<slrnnr3382.451.peter@box8.pjb.com.au>
In reply to#2774
On 2016-08-15, John Forkosh <forkosh@panix.com> wrote:
> Very nice. I tested it with various other x,y1...x,yn's,
> and it seems to behave pretty nicely for the stuff I tested.

I found a bit of a problem when I tried
  [ 250 300  240 400  260 390  250 600 ] points2curve stroke
in other words with a short segment at an acute angle (around p4);
I decided that in order to calculate p3 and p5 it's safer to
scale with the _shorter_ of the two segments. So when I wrote that:
  and I think if p1-to-p4 is a long segment and p4-to-p7 is a short
  one, then it probably looks better if p3-to-p4 is reasonable in the
  p1-to-p4 context, and p4-to-p5 reasonable in its p4-to-p7 context.
  Needs trying out
well I tried it, and it turned out luser.droog was right :-)
So anyway, the currently quite useable version is rolled into
  http://www.pjb.com.au/comp/line_drawing.html#points2curve
as planned, and you can get it in
  http://www.pjb.com.au/comp/free/line_drawing.ps.txt
or in github:
  https://github.com/peterbillam/postscriptlib
but I can also post the new procedure here if people want ...
I'll road-test it a bit over the next few days.

> Like you, I put together some ps for "arty stuff" (your
> words above), and you might find some of that useful. See
>   http://www.forkosh.com/images/decorative/decorative13.jpg
> for an example. Same_directory/decorative13.ps has all the ps.

Very nice :-)  With that kind of image, I always dream about
gradually changing the parameters, generating hundreds of them
(maybe 1600x900) and putting them together into a movie !
(thinks: fame, fortune) but I never get around to it, though.

Peter

-- 

Peter Billam    www.pjb.com.au    www.pjb.com.au/comp/contact.html

[toc] | [prev] | [next] | [standalone]


#2776

FromJohnF <john@please.see.sig.for.email.com>
Date2016-08-16 01:28 +0000
Message-ID<notq8d$c09$1@reader2.panix.com>
In reply to#2775
Peter Billam <peter@www.pjb.com.au> wrote:
> On 2016-08-15, John Forkosh <forkosh@panix.com> wrote:
>> Very nice. I tested it with various other x,y1...x,yn's,
>> and it seems to behave pretty nicely for the stuff I tested.
> 
> I found a bit of a problem when I tried
>  [ 250 300  240 400  260 390  250 600 ] points2curve stroke
> in other words with a short segment at an acute angle (around p4);
> I decided that in order to calculate p3 and p5 it's safer to
> scale with the _shorter_ of the two segments. So when I wrote that:
>  and I think if p1-to-p4 is a long segment and p4-to-p7 is a short
>  one, then it probably looks better if p3-to-p4 is reasonable in the
>  p1-to-p4 context, and p4-to-p5 reasonable in its p4-to-p7 context.
>  Needs trying out
> well I tried it, and it turned out luser.droog was right :-)
> So anyway, the currently quite useable version is rolled into
>  http://www.pjb.com.au/comp/line_drawing.html#points2curve
> as planned, and you can get it in
>  http://www.pjb.com.au/comp/free/line_drawing.ps.txt
> or in github:
>  https://github.com/peterbillam/postscriptlib
> but I can also post the new procedure here if people want ...
> I'll road-test it a bit over the next few days.

Thanks. I guess I didn't test it thoroughly (and wasn't really
sure where the "rough edges" that I'd want to thoroughly test are).
Please do re-post when you're satisfied with it (not necessarily
the procedure itself, but just the fact it's "ready for prime time").
Some of my "arty stuff" also does bezier, e.g.,
   http://www.forkosh.com/images/decorative/decorative8.jpg
and the corresponding .ps, which shows the /curvestep function.
I was thinking of maybe adding another such function based on
your points2curve, though at the moment I don't have any designs
in mind that would use it.

>> Like you, I put together some ps for "arty stuff" (your
>> words above), and you might find some of that useful. See
>>   http://www.forkosh.com/images/decorative/decorative13.jpg
>> for an example. Same_directory/decorative13.ps has all the ps.
> 
> Very nice :-)  With that kind of image, I always dream about
> gradually changing the parameters, generating hundreds of them
> (maybe 1600x900) and putting them together into a movie !
> (thinks: fame, fortune) but I never get around to it, though.
> Peter

Yeah, check out
   http://www.forkosh.com/images/decorative/decofweek.gif
and the corresponding .ps file. That's an animated gif design.
I used imagemagick  convert whatever.ps whatever.gif  to do that.
Each  %%Page: ... showpage  of the .ps gets interpreted as
a separate frame of the gif animation. Not exactly a movie,
but maybe accomplishes some of what you might be thinking.
-- 
John Forkosh  ( mailto:  j@f.com  where j=john and f=forkosh )

[toc] | [prev] | [next] | [standalone]


#2778

FromPeter Billam <peter@www.pjb.com.au>
Date2016-08-16 23:32 +0000
Message-ID<slrnnr78k2.1pc.peter@box8.pjb.com.au>
In reply to#2776
> Peter Billam <peter@www.pjb.com.au> wrote:
>> I'll road-test it a bit over the next few days.

I found a bug:
  2 setlinewidth /Helvetica 16 selectfont
  70 600 moveto (right to left) show
  [ 450 700  350 680  250 720  150 680   50 700 ] points2curve
  [ 450 500  350 520  250 480  150 520   50 500 ] points2curve
  70 200 moveto (left to right) show
  [  50 300  150 280  250 320  350 280  450 300 ] points2curve
  [  50 100  150 120  250  80  350 120  450 100 ] points2curve
  stroke

It comes from "bisecting an angle": If I average 1 and -1 that's 0
but average 1 and 359 and I get 180. On the other side of the circle
then it's the same the other way round; average 179 and -179 I get 0
but 179 and 181 I get 180.  I think I trod in something quite deep,
like one of Penrose's spinor things where you have to go round
twice just to get back to the same place.

I tried All Sorts of combinations of  if else add sub gt lt
and ended up with a combination that works :-) though I don't
really understand what it's  doing :-(   There must be a
neater way to do it...  Anyway, the core of the fix is:

p_ip1_x p_im1_x gt angle_before 180 sub angle_after 180 sub mul 0 lt and {
  angle_before 180 ge { /angle_before angle_before 360 sub def } if
  angle_after  180 gt { /angle_after  angle_after  360 sub def } if
} if

On 2016-08-16, JohnF <john@please.see.sig.for.email.com> wrote:
> Please do re-post when you're satisfied with it (not necessarily
> the procedure itself, but just the fact it's "ready for prime time").

So check out:
  http://www.pjb.com.au/comp/line_drawing.html#points2curve
  http://www.pjb.com.au/comp/line_drawing.html#install
  https://github.com/peterbillam/postscriptlib

or the source:
  http://www.pjb.com.au/comp/free/line_drawing.ps.txt
and look for points2curve.  It seems to work :-)

Regards,  Peter

-- 

Peter Billam    www.pjb.com.au    www.pjb.com.au/comp/contact.html

[toc] | [prev] | [next] | [standalone]


#2779

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2016-08-17 01:07 -0400
Message-ID<pk4zlvwvmckx.156cvc0ua546z.dlg@40tude.net>
In reply to#2778
On 16 Aug 2016 23:32:20 GMT, Peter Billam wrote:

> It comes from "bisecting an angle": If I average 1 and -1 that's 0
> but average 1 and 359 and I get 180. On the other side of the circle
> then it's the same the other way round; average 179 and -179 I get 0
> but 179 and 181 I get 180.

The necessary insight comes once you accept you're not just "averaging"
numbers (an arithmetic problem): you're finding the point, on a circular
dial-face, half-way -- going (your choice) counterclockwise (CCW) or
clockwise (CW) -- between one point and another (a geometric problem).

Halfway (on a clock-face) from 11 to 1, CW, you meet 12; same problem CCW,
though, and you meet 6 instead. No surprises there. 

Another way to put it: you're not bisecting an "angle" -- you're bisecting
an *arc*, and it's not enough to know the end-points of that arc: you also
need to know which of the two circular fragments having those endpoints is
the arc you are really seeking to bisect (seeking the midpoint of).

Once the problem has been clearly identified, I'm sure it becomes easier to
find an unambiguously correct solution to it :-) .

HTH. Cheers, -- tlvp
-- 
Avant de repondre, jeter la poubelle, SVP.

[toc] | [prev] | [next] | [standalone]


#2771

FromJohnF <john@please.see.sig.for.email.com>
Date2016-08-14 06:17 +0000
Message-ID<nop2el$j5o$1@reader2.panix.com>
In reply to#2763
luser droog <luser.droog@gmail.com> wrote:
> On Friday, August 12, 2016 at 3:10:09 AM UTC-5, Peter Billam wrote:
>> Hi.  There must be reasonable ways of constructing a series
>> of curveto's that go smoothly through a given array of points
>> [x1 y1 x2 y2 ... xN yN] ...  Anyone here written stuff like that,
>> or know of where it could be found ?
>>    If I do it, it'll turn out very ad-hoc and heuristic-ish,
>> with lots of arrays-of-points that cause wild behaviour :-(
> 
> Somewhat on the same level as tlvp's thoughts, I have a few 
> observations about Bezier curves. Everybody probably knows
> these things already, but perhaps I can describe them in a
> novel way.
> 
> A cubic Bezier curve in 2D is determined by 4 coordinate pairs,
> x1 y1, x2 y2, x3 y3, x4 y4, and passes through points 1 and 4.
> The vectors from the interior points to their adjacent outer
> points determine the tangents as the curve passes through those
> same outer points.
> 
> In ascii-art,
> 
>      .      .
> .    p2     p3    .
> p1                p4
> 
> The trace of the curve from t=0 to t=1 starts at p1, then moves 
> toward p2, along the vector p2-p1. As the curve progresses, the
> weight associated with the p2-p1 tangent vector goes from 1 to 0.
> At the same time the weight associated with the p4-p3 tangent
> vector goes from 0 to 1. So the instant the curve crosses the
> finish t=1, it is wholly under the control of the exiting tangent
> vector p4-p3.
> 
> Now with some calculus background, we learn that tangents in general
> can be found by taking the derivative of a function. The first 
> derivative, evaluated at a specific value for t, gives the "slope"
> at the corresponding point of the original function for the same t 
> value. The second derivative gives the "curvature" or acceleration,
> how much the slope is changing.
> 
> The practical upshot (and skipping a few steps) is, to smoothly 
> connect two Bezier curves at a join, first the inner control
> points adjacent to the join point need to be collinear. This gives
> gives you matching slopes as the curve crosses the join.
> 
>      .      .
> .    p2     p3    .                 .
> p1                p4    .     .     p7
>                         p5    p6
> 
> <p3, p4, p5> need to be collinear.
> 
> To match curvature, the magnitudes of the adjacent tangent vectors
> need to be the same (or not too different).
> 
> |p4-p3| ~= |p5-p4|
> 
> So what remains is the "outer" inner control points, p2 and p6.
> With no rigor at all, my guess is they should be collinear with
> their adjacent control points.
> 
> So, not an algorithm. But maybe this can help someone else come
> up with something.

Maybe see

http://stackoverflow.com/questions/7715788/find-bezier-control-points-for-curve-passing-through-n-points

for additional discussion.
-- 
John Forkosh  ( mailto:  j@f.com  where j=john and f=forkosh )

[toc] | [prev] | [next] | [standalone]


#2777

Fromjdaw1 <jdawiseman@gmail.com>
Date2016-08-16 03:14 -0700
Message-ID<8adff818-c4cd-46fd-8767-7da9074c3f1c@googlegroups.com>
In reply to#2753
This was MacDraw II used to do, back in the late 1980s. Does anybody know MacDraw (II)’s actual algorithm?

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.postscript


csiph-web