Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #3423
| Newsgroups | comp.lang.postscript |
|---|---|
| Date | 2019-07-20 13:18 -0700 |
| Message-ID | <bcebd98c-b6bf-47fb-bfa9-bc064429190b@googlegroups.com> (permalink) |
| Subject | Snipping the ears |
| From | luser droog <luser.droog@gmail.com> |
After 27 posts in the other thread, I thought it'd be nice to
have a fresher start on the remaining issues with my code.
The task is to take the glyph of the number 9 using 'charpath',
then traverse the curves like a turtlw with a paintbrush hanging
out one arm's-length away.
The tricky part would be dealing with the actual Bezier curves,
so I call 'flattenpath' first so I can work with just line
segments. The 'setflat' operator can be used to control how
finely the curves are cut into line segments.
(Or maybe, the curves true secret path to the desired result??)
Anyway, to traverse the line segments I use a control structure
I cooked up, called 'fortuplem'. It works kind of like 'forall',
but it takes 2 parameters n and m. n is the step-value between
iterations, and m is the width of a slice of the array produce
using 'getinterval'. Calling with n=2 m=2 iterates over the
points in the line. Calling with n=2 m=4 iterates over 2 point
slices. So I can run through these 2 points slices, get a vector
between them, normalize, take the perpendicular vector, scale
by my "arm's length" and produce a new transformed point.
This just needs one special case for the wrap around the end
from the last point to the first.
So, this all *works* with the untidy caveat that it produces
"ears" when the input path has a tight bend in the curve.
Detecting and pruning these ears would make the output nicer
and more usable. A further nicety would be implementing miter
or bevel joins for the other side of the tight bends.
Any, here's the current state of the code, including the laborious
fixes for the 2 "hacks" described at the end of the last thread.
$ cat stroke2.ps
%!
% Generate offset curves by traversing input path.
/args-begin { dup length dict begin { exch def } forall } def
/map { [ 3 1 roll forall ] } def
/spill { aload pop } def
/head { 0 exch getinterval } def
/tail { 1 index length 1 index sub getinterval } def
/last { 1 index length 1 index sub exch getinterval } def
/droplast { 1 index length exch sub 0 exch getinterval } def
/fortuplem {
{p m n a} args-begin
0 n /a load length m sub
[ /a load /exch cvx m /getinterval cvx /p load /exec cvx ] cvx
end for
} def
/p-p { exch 3 1 roll sub 3 1 roll sub exch } def
/p+v { exch 3 1 roll add 3 1 roll add exch } def
/v*n { 3 2 roll 1 index mul 3 1 roll mul } def
/perp { neg exch } def
/norm {
2 copy dup mul exch dup mul exch add sqrt
1 exch div v*n
} def
/closedsubpaths { [ {[ 3 1 roll} {} {} {]} pathforall ] {{]}stopped{exit}if}loop } def
/drawpath {
{
dup length 2 eq { spill moveto }{
dup 2 head spill moveto
2 tail 2 2 { spill lineto } fortuplem
closepath
} ifelse
} forall
} def
/offsetbyvectors {
/n exch def
{
dup length 2 ne {
suppresszerovectors
offsetsubpath
suppresszerovectors
} if
} map
} def
/suppresszerovectors {
%2 droplast
dup vectors zeros %dup ==
suppresspairs
} def
/vectors {
[ exch
dup 2 4 { spill p-p } fortuplem
counttomark -1 roll
dup 2 last spill 3 2 roll 2 head spill p-p
]
} def
/threshold 0.7 def
/iszero {
%0 eq
abs threshold lt
} def
/zeros {
[ exch
2 2 { spill iszero exch iszero and } fortuplem
]
} def
/suppresspairs { % pairs zeros
false { % p z restart
0 1 3 index length 1 sub { % p z r i
2 index 1 index get % p z r i z_i
{ % p z r i |true
snippair % p' z' r'
exit
}{ % p z r i |false
pop % p z r
} ifelse
} for
not { exit } if false
} loop % p' z'
pop % pairs'
} def
/snippair { % p z r i
true 5 1 roll exch pop % r' p z i
2 copy snipsing 5 1 roll % z' r' p z i
exch pop snippair_ % z' r' p'
3 1 roll % p' z' r'
} def
/snipsing { % array i
2 copy head 3 1 roll
1 add tail cat
} def
/cat { 2 array astore {spill} map } def
/snippair_ { % array i
2 mul
2 copy head 3 1 roll
2 add tail cat
} def
/offsetsubpath {
[ exch
dup 2 4 { offsetvec } fortuplem
counttomark -1 roll
dup 2 last spill 3 2 roll 2 head spill 4 array astore offsetvec
]
} def
/offsetvec {
dup 0 2 getinterval spill 3 2 roll
spill %4 2 roll
p-p norm n v*n
perp p+v
} def
/offsetpath {
closedsubpaths exch
offsetbyvectors
newpath
drawpath
} def
/Calibri-Bold 600 selectfont
100 100 moveto (9) true charpath
gsave stroke grestore
gsave
20 setlinewidth strokepath
1 setlinewidth
%stroke
grestore
1 0 0 setrgbcolor
flattenpath
gsave
10 offsetpath
stroke
grestore
-10 offsetpath
stroke
showpage quit
Back to comp.lang.postscript | Previous | Next — Next in thread | Find similar
Snipping the ears luser droog <luser.droog@gmail.com> - 2019-07-20 13:18 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-07-20 16:51 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-07-22 00:47 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-07-24 00:38 -0700
Re: Snipping the ears Mark Carroll <mtbc@bcs.org> - 2019-07-24 08:50 +0100
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-07-29 23:18 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-08-06 22:05 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-08-08 00:22 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-08-11 13:33 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-08-13 16:03 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-08-19 22:46 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-08-21 23:44 -0700
Re: Snipping the ears jdaw1 <jdawiseman@gmail.com> - 2019-10-10 15:07 -0700
Re: Snipping the ears jdaw1 <jdawiseman@gmail.com> - 2019-10-10 15:09 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-10-13 01:39 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2019-10-13 01:51 -0700
Re: Snipping the ears jdaw1 <jdawiseman@gmail.com> - 2020-06-04 03:15 -0700
Re: Snipping the ears luser droog <luser.droog@gmail.com> - 2020-07-09 10:31 -0700
Re: Snipping the ears jdaw1 <jdawiseman@gmail.com> - 2021-02-13 09:51 -0800
csiph-web