Abuse clipping to avoid intersecting lines?

27 views
Skip to first unread message

luser- -droog

unread,
Nov 30, 2011, 9:29:23 PM11/30/11
to
I'm trying to do some music typesetting and I need to draw
lots of vertical lines (note-stem extensions) up to a roughly-
horizontal line (the cross-beam joining notes into a figure).

I think I can use the clipping path to avoid calculating all those
line-intersections by: scaling up the ctm really big, drawing the
horizontal, eoclip to cut the clipping region in half (in a trapezoid
shape), and then draw extra-long verticals with auto-clipped
edges.

So the question is: Is there a standard orientation for the clipping
path ([Counter]Clockwise)? Knowing this, I could choose which
half of the clip-region I want by drawing the line left-right vs.
right-left, right?

luser- -droog

unread,
Nov 30, 2011, 9:42:25 PM11/30/11
to
Wouldn't it be awesome if there were a wedge-tip pen with ink on one
half and white-out on the other?

luser- -droog

unread,
Dec 2, 2011, 2:35:32 PM12/2/11
to
On Nov 30, 8:29 pm, luser- -droog <mijo...@yahoo.com> wrote:

> So the question is: Is there a standard orientation for the clipping
> path ([Counter]Clockwise)? Knowing this, I could choose which
> half of the clip-region I want by drawing the line left-right vs.
> right-left, right?

No, that can't work. I'll have to `clippath pathforall` and redraw
the
path with my new line already incorporated. And I don't need eoclip,
do I?
I think regular clip should do it.

Olle

unread,
Dec 13, 2011, 4:18:48 PM12/13/11
to
Not sure if I understand this correctly, but would something like this
do?

<your (double) line width><your path> gsave 1 setgray stroke grestore
fill

Thanks,

Olle

Olle

unread,
Dec 13, 2011, 9:34:13 PM12/13/11
to
> Olle- Hide quoted text -
>
> - Show quoted text -

The previous was some kind of answer to the wedge-tip pen question.

But how about something like this:
- stroke your nearly horizontal
- gsave
- create a clip path starting, say, from the end coordinates of the
stroke, going on far enough right, far enough down, far enough left,
up to the y-coordinate of the beginning of the stroke, to the begin
coordinates, closepath (switching down to up and vice versa if your
notes are upside down)
- do your notes
- grestore
?

Thanks,

Olle

luser- -droog

unread,
Dec 14, 2011, 12:48:29 AM12/14/11
to
Yes! That's much simpler.
No need to take the clippath at all.
I just need to construct the "rest of the box" with generous
dimensions.

I'm kind of stalled on this project until amazon brings my
new music engraving books; but I did try to work-up some
code to handle beaming the stems together into figures.
But the whole thing looks funny with perfectly horizontal
beams. And I've got bad joins! Particularly, the bottom right
corner. I see now why muscript draws the beams as rectangles.
(I'm hoping the books will have guidance on this.)

But the notehead is super-simple now: just 2 curves with
control points arranged like a 6-point domino.

%!

%draw a closed curve 1.5x1 around 0,0
/jigger {
0 .5 moveto
1 0 1 -1 0 -1 rcurveto
-1 0 -1 1 0 1 rcurveto closepath
} def

%draw note head (draw n shrinking curves at x,y and eofill)
/head { %n x y head -
gsave translate
jigger { .7 .9 scale jigger } repeat
eofill grestore
} def

%draw a down-stem
/down {
moveto
-0.75 0 rmoveto
0 -4 2 copy rlineto .12 0 rlineto neg rlineto fill
} def

%draw an up-stem
/up {
moveto
.75 0 rmoveto
0 4 2 copy rlineto -.12 0 rlineto neg rlineto fill
} def

100 500 translate
20 20 scale
.3 setlinewidth

{ gsave
3 {
0 0 0 head 0 0 up
0 2 2 head 2 2 up
0 4 0 head 4 0 up
0 6 2 head 6 2 up
8 0 translate
} repeat
grestore
0 -10 translate
} pop%exec

/a [0 2 0 2 0 2 0 2 0 2 0 2] def
0 a {
0 exch 2 index exch
2 copy down
dup 0 gt { 2 copy pop 0 down } if
head
2 add
} forall

-0.75 -4 moveto 22 -0.75 add -4 lineto stroke
-0.75 -3.5 moveto 22 -0.75 add -3.5 lineto stroke
-0.75 -3.0 moveto 6 -0.75 add -3.0 lineto stroke
8 -0.75 add -3.0 moveto 14 -0.75 add -3.0 lineto stroke
16 -0.75 add -3.0 moveto 22 -0.75 add -3.0 lineto stroke
-0.75 -2.5 moveto 6 -0.75 add -2.5 lineto stroke
8 -0.75 add -2.5 moveto 14 -0.75 add -2.5 lineto stroke
16 -0.75 add -2.5 moveto 22 -0.75 add -2.5 lineto stroke

tlvp

unread,
Dec 14, 2011, 12:33:52 PM12/14/11
to
On Tue, 13 Dec 2011 21:48:29 -0800 (PST), luser- -droog wrote:

> ... but I did try to work-up some
> code to handle beaming the stems together into figures.
> But the whole thing looks funny with perfectly horizontal
> beams.

Just two thoughts from a former child note reader (piano & voice):

1) notes are sort of ellipsoidal, with the major axis tilted
ever so slightly WSW/ENE-ward (rather than being true W/E; and

2) yes, the eighth/sixteenth/etc. bars (your "beams") are ... umm
... not exactly rectangular, but rather parallelograms, with short
side vertical and long side usually either slightly WSW/ENE-erly or
slightly WNW/ESE-erly.

As for exact values of "slightly" -- I'd have to experiment to see.

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

luser- -droog

unread,
Dec 14, 2011, 10:04:32 PM12/14/11
to
Sounds like a job for a skewed coordinate space.
Then the amount of WSW/ENE-erliness could be globally controlled.

That is, unless it can be managed by controlling the pen shape.
With a tall, thin pen you could draw the outer stems and lowest beam
as a single path, then stroke would join them naturally.

luser- -droog

unread,
Dec 14, 2011, 11:14:14 PM12/14/11
to
Here's a step in that direction. I like the note shape very much now.
And no more looping eofill nonsense. Just fill or stroke with a fat
pen.

%!

/notepen {
20 2
matrix defaultmatrix dup setmatrix
scale concat
} def

/stempen {
2 30
matrix defaultmatrix dup setmatrix
scale concat
} def

%draw a closed curve 1.5x1 around 0,0
%arranged like a floppy domino.
% * **
% ** *
/jigger {
0 .5 moveto
.8 0 1.2 -1 0 -1 rcurveto
-.8 0 -1.2 1 0 1 rcurveto closepath
} def

%draw note head (draw n shrinking curves at x,y and eofill)
/head { %n x y head -
gsave translate
jigger %{ .7 .9 scale jigger } repeat %eofill
[{fill}{notepen stroke}] exch get exec
grestore
} def

%draw a down-stem
/down {
moveto
-0.70 0 rmoveto
gsave
0 -4 rlineto
stempen stroke grestore
%0 -4 2 copy rlineto .12 0 rlineto neg rlineto fill
} def

%draw an up-stem
/up {
moveto
.70 0 rmoveto
gsave
0 4 rlineto
stempen stroke grestore
%0 4 2 copy rlineto -.12 0 rlineto neg rlineto fill
} def

100 500 translate
20 20 scale
.3 setlinewidth

{ gsave
3 {
1 0 0 head 0 0 up
1 2 2 head 2 2 up
1 4 0 head 4 0 up
1 6 2 head 6 2 up
8 0 translate
} repeat
grestore
0 -10 translate
} exec

/a [0 2 0 2 0 2 0 2 0 2 0 2] def
0 a {
0 exch 2 index exch
2 copy down
dup 0 gt { 2 copy pop 0 down } if
head
2 add
} forall

/stroke { gsave stempen stroke grestore newpath } bind def

luser- -droog

unread,
Dec 14, 2011, 11:31:46 PM12/14/11
to
On Dec 14, 10:14 pm, luser- -droog <mijo...@yahoo.com> wrote:
>
> %draw a closed curve 1.5x1 around 0,0
> %arranged like a floppy domino.
> % * **
> %  ** *
> /jigger {
>     0 .5 moveto
>     .8 0 1.2 -1 0 -1 rcurveto
>     -.8 0 -1.2 1 0 1 rcurveto closepath
>
> } def
>

Sorry, I had it flopped the wrong way ;)
This is what I imagined I was seeing
before I saw what I was looking at:


%draw a closed curve 1.5x1 around 0,0
%arranged like a floppy domino.
% ** *
% * **
/jigger {
0 .5 moveto
1.2 0 .8 -1 0 -1 rcurveto
-1.2 0 -.8 1 0 1 rcurveto closepath
} def

luser- -droog

unread,
Dec 15, 2011, 4:50:32 AM12/15/11
to
This one actually does the trapezoid clipping.
I went with a beam angle of half the y-displacement
of the perimeter notes. But it looks like I can't
avoid line-intersections to get the sub-beams.
(Unless setdash will serve?!)

It also looks like I may need to kern the noteheads.

%!

/notepen {
20 4
matrix defaultmatrix dup setmatrix
scale concat
} def

/stempen {
8 25
matrix defaultmatrix dup setmatrix
scale concat
} def

%draw a closed curve 1.5x1 around 0,0
%arranged like a floppy domino.
% ** *
% * **
/jigger {
0 .5 moveto
1.2 0 .8 -1 0 -1 rcurveto
-1.2 0 -.8 1 0 1 rcurveto closepath
} def

100 600 translate
20 20 scale
.3 setlinewidth

{ gsave
3 {
1 0 0 head 0 0 up
1 2 2 head 2 2 up
0 4 0 head 4 0 up
0 6 2 head 6 2 up
8 0 translate
} repeat
grestore

0 -10 translate
} exec

/a [0 2 0 2 0 2 0 2 0 2 0 2] def

{
0 a {
0 exch 2 index exch
2 copy down
dup 0 gt { 2 copy pop 0 down } if
head
2 add
} forall

/stroke { gsave stempen stroke grestore newpath } bind def

-0.75 -4 moveto 22 -0.75 add -4 lineto stroke
-0.75 -3.5 moveto 22 -0.75 add -3.5 lineto stroke
-0.75 -3.0 moveto 6 -0.75 add -3.0 lineto stroke
8 -0.75 add -3.0 moveto 14 -0.75 add -3.0 lineto stroke
16 -0.75 add -3.0 moveto 22 -0.75 add -3.0 lineto stroke
-0.75 -2.5 moveto 6 -0.75 add -2.5 lineto stroke
8 -0.75 add -2.5 moveto 14 -0.75 add -2.5 lineto stroke
16 -0.75 add -2.5 moveto 22 -0.75 add -2.5 lineto stroke

0 -10 translate
} exec

/adj{-.75 add}def

0 0 a {
3 copy head
pop
2 add
} forall pop pop

0 adj a 0 get moveto
0 adj -4 lineto % left
22 adj -3 lineto % beam
22 adj a 11 get lineto % right
gsave stempen stroke grestore %draw the lines
22 adj 10 lineto
0 adj 10 lineto
closepath clip %complete the trapezoid and clip
newpath

0 adj -3.5 moveto 22 adj -2.5 lineto % second beam

%draw the remaining stems
2 adj 1 1 11 {
a exch get % x y
2 copy moveto pop
currentpoint pop -10 lineto
2 add
} for pop

{ %need to calculate intersections for the beams!
[[0 3][4 7][8 11]]{
{ dup 2 mul exch a exch get
} forall moveto lineto
} forall
}pop
0 adj -3 moveto 22 adj -2 lineto
0 adj -2.5 moveto 22 adj -1.5 lineto

stempen stroke

luser- -droog

unread,
Dec 15, 2011, 1:21:24 PM12/15/11
to
On Dec 15, 3:50 am, luser- -droog <mijo...@yahoo.com> wrote:
> This one actually does the trapezoid clipping.
> I went with a beam angle of half the y-displacement
> of the perimeter notes. But it looks like I can't
> avoid line-intersections to get the sub-beams.
> (Unless setdash will serve?!)

Hurray for setdash! The tricky part is the dash-lengths
are in "pen" coordinates, rather than "path" coordinates.

>
[snip]
>
> { %need to calculate intersections for the beams!
> [[0 3][4 7][8 11]]{
>     { dup 2 mul exch a exch get
>     } forall moveto lineto} forall
> }pop
>

gsave stempen stroke grestore newpath
[15 5] 0 setdash

luser- -droog

unread,
Dec 16, 2011, 1:24:20 AM12/16/11
to
On Dec 13, 8:34 pm, Olle <olavi.sak...@gmail.com> wrote:
> On Dec 13, 2:18 pm, Olle <olavi.sak...@gmail.com> wrote:
> > On Nov 30, 7:42 pm, luser- -droog <mijo...@yahoo.com> wrote:

> > > Wouldn't it be awesome if there were a wedge-tip pen with ink on one
> > > half and white-out on the other?
>
> > Not sure if I understand this correctly, but would something like this
> > do?
>
> > <your (double) line width><your path> gsave 1 setgray stroke grestore
> > fill
>
> > Thanks,
>
> > Olle- Hide quoted text -
>
> > - Show quoted text -
>
> The previous was some kind of answer to the wedge-tip pen question.

This time I was imagining a real, physical object. A hand-tool.

There is a nice white-out pen now. And calligraphy pens with
wedge tips. I was imagining them combined in one stylus, with
a two-channel, divided nib, like an epoxy applicator.
Reply all
Reply to author
Forward
0 new messages