Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #2753 > unrolled thread
| Started by | Peter Billam <peter@www.pjb.com.au> |
|---|---|
| First post | 2016-08-12 08:10 +0000 |
| Last post | 2016-11-05 10:12 -0700 |
| Articles | 20 on this page of 29 — 9 participants |
Back to article view | Back to comp.lang.postscript
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 →
| From | Peter Billam <peter@www.pjb.com.au> |
|---|---|
| Date | 2016-08-12 08:10 +0000 |
| Subject | a 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]
| From | Lawrence D’Oliveiro <lawrencedo99@gmail.com> |
|---|---|
| Date | 2016-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]
| From | tlvp <mPiOsUcB.EtLlLvEp@att.net> |
|---|---|
| Date | 2016-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]
| From | tlvp <mPiOsUcB.EtLlLvEp@att.net> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Lawrence D’Oliveiro <lawrencedo99@gmail.com> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Peter Billam <peter@www.pjb.com.au> |
|---|---|
| Date | 2016-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]
| From | Peter Billam <peter@www.pjb.com.au> |
|---|---|
| Date | 2016-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]
| From | John Forkosh <forkosh@panix.com> |
|---|---|
| Date | 2016-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]
| From | Peter Billam <peter@www.pjb.com.au> |
|---|---|
| Date | 2016-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]
| From | JohnF <john@please.see.sig.for.email.com> |
|---|---|
| Date | 2016-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]
| From | Peter Billam <peter@www.pjb.com.au> |
|---|---|
| Date | 2016-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]
| From | tlvp <mPiOsUcB.EtLlLvEp@att.net> |
|---|---|
| Date | 2016-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]
| From | JohnF <john@please.see.sig.for.email.com> |
|---|---|
| Date | 2016-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]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2016-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