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


Groups > comp.lang.postscript > #3423

Snipping the ears

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>

Show all headers | View raw


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 | NextNext in thread | Find similar


Thread

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