ntg-context - mailing list for ConTeXt users
 help / color / mirror / Atom feed
* Clipping a path to a boundary --- Being more specific
@ 2005-08-08  1:17 David Arnold
  2005-08-08 13:20 ` Hans Hagen
  0 siblings, 1 reply; 4+ messages in thread
From: David Arnold @ 2005-08-08  1:17 UTC (permalink / raw)


Hans et al,

Let me try to be more specific. Here is a file which is very typical of 
the way I draw graphs for my mathematics classes. When you compile, you 
will see the graph of the absolute value of x-1. That is, it draws the 
graph of y=|x-1|, but only after clipping it to the cpath.  What I 
would like to do is draw the graph with the drawdblarrow command so 
that the graph of the absolute value ends in arrowheads. So, I want to 
clip the graph to the bounding box, save the picture, null the picture, 
then somehow extract the path into the variable F in its clipped form 
(not the original path F that extends outside the clip path) so that I 
can replace the command draw pic with drawdblarrow F.

beginfig(0);

numeric a, c;
a=1;

% define function f(x)=|x-a|
vardef f(expr x)=
	abs(x-a)
enddef;

% draw line with given point and slope
path F;
F:=(-5,f(-5));
for x=-5 step 1 until 5:
	F:=F--(x,f(x));
endfor;

% initialize scale
numeric u; 10u=3in;

% the line
F:=F scaled 1u;
draw F withcolor blue;

% clipping path
path cpath;
cpath:=(-5,-5)--(5,-5)--(5,5)--(-5,5)--cycle;
cpath:=cpath scaled 1u;

% clip and save current picture
picture pic;
clip currentpicture to cpath;
pic:=currentpicture;
currentpicture:=nullpicture;

% erase currentpicture
currentpicture:=nullpicture;

% draw grid
for k=-5u step 1u until 5u:
	draw (-5u,k)--(5u,k) withcolor 0.85white;
	draw (k,-5u)--(k,5u) withcolor 0.85white;
endfor;

% draw axes
drawarrow (-5u,0)--(5u,0);
drawarrow (0,-5u)--(0,5u);

% label axes
label.rt(btex $x$ etex, (5.2u,0));
label.top(btex $y$ etex, (0,5.2.u));
label.bot(btex $5$ etex, (5u,0));
label.lft(btex $5$ etex, (0,5u));

% redraw line
draw pic;

endfig;

end.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Clipping a path to a boundary --- Being more specific
  2005-08-08  1:17 Clipping a path to a boundary --- Being more specific David Arnold
@ 2005-08-08 13:20 ` Hans Hagen
  2005-08-10  0:24   ` David Arnold
  0 siblings, 1 reply; 4+ messages in thread
From: Hans Hagen @ 2005-08-08 13:20 UTC (permalink / raw)


David Arnold wrote:

> Hans et al,
>
> Let me try to be more specific. Here is a file which is very typical 
> of the way I draw graphs for my mathematics classes. When you compile, 
> you will see the graph of the absolute value of x-1. That is, it draws 
> the graph of y=|x-1|, but only after clipping it to the cpath.  What I 
> would like to do is draw the graph with the drawdblarrow command so 
> that the graph of the absolute value ends in arrowheads. So, I want to 
> clip the graph to the bounding box, save the picture, null the 
> picture, then somehow extract the path into the variable F in its 
> clipped form (not the original path F that extends outside the clip 
> path) so that I can replace the command draw pic with drawdblarrow F.


hm, this need some more brainpower than the previous solution,

in mp-tool there is a repathed macro that does most of the job so let's 
extend that one a bit:

\starttext

\setupcolors[state=start]

\startMPpage

def restroke  suffix p = p := repathed (21,p) enddef ; % keep attributes
def reprocess suffix p = p := repathed (22,p) enddef ; % no attributes

vardef repathed (expr mode, p) text t =
  begingroup ;
  if mode=0 : save withcolor ; remapcolors ; fi ;
  save _p_, _pp_, _ppp_, _f_, _b_, _t_ ;
  picture _p_, _pp_, _ppp_ ; color _f_ ; path _b_ ; transform _t_ ;
  _b_ := boundingbox p ; _p_ := nullpicture ;
  for i within p :
    _f_ := (redpart i, greenpart i, bluepart i) ;
    if     bounded i :
      _pp_ := repathed(mode,i) t ;
      setbounds _pp_ to pathpart i ;
      addto _p_ also _pp_ ;
    elseif clipped i :
      _pp_ := repathed(mode,i) t ;
      clip _pp_ to pathpart i ;
      addto _p_ also _pp_ ;
    elseif stroked i :
      if mode=21 :
        _ppp_ := i ; % indirectness is needed
        addto _p_ also image(scantokens(t & " pathpart _ppp_")
          dashed dashpart i withpen penpart i
          withcolor _f_ ; ) ;
      elseif mode=22 :
        _ppp_ := i ; % indirectness is needed
        addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
      else :
        addto _p_ doublepath pathpart i
          dashed dashpart i withpen penpart i
          withcolor _f_ % (redpart i, greenpart i, bluepart i)
          if mode=2 : t fi ;
      fi ;
    elseif filled  i :
      if mode=11 :
        _ppp_ := i ; % indirectness is needed
        addto _p_ also image(scantokens(t & " pathpart _ppp_")
          withcolor _f_ ; ) ;
      elseif mode=12 :
        _ppp_ := i ; % indirectness is needed
        addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
      else :
        addto _p_ contour pathpart i
          withcolor _f_
        if (mode=1) and (_f_<>refillbackground) : t fi ;
      fi ;
    elseif textual i : % textpart i <> "" :
      if mode <> 4 :
        addto _p_ also i if mode=3 : t fi ;
      fi ;
    else :
      addto _p_ also i ;
    fi ;
  endfor ;
  setbounds _p_ to _b_ ;
  _p_
  endgroup
enddef ;


    picture pic; pic := image(
        draw fullcircle scaled 5cm withpen pencircle scaled 5mm ;
        draw fullsquare scaled 2cm withpen pencircle scaled 5mm ;
        fill fullcircle scaled 1cm withpen pencircle scaled 5mm ;
    ) ;

    redraw pic withpen pencircle scaled 1mm withcolor red ;
%     restroke pic "drawdblarrow" ;
    pic := repathed(21,pic) "drawdblarrow" ;
    pic := repathed(11,pic) "drawdblarrow" ;
    draw pic ;

\stopMPpage

\stoptext

the new restroke variant takes a macro name that itself takes one argument, i.e. a path, so in order to do more complex things, you need to define those 

Hans 

-----------------------------------------------------------------
                                          Hans Hagen | PRAGMA ADE
              Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
     tel: 038 477 53 69 | fax: 038 477 53 74 | www.pragma-ade.com
                                             | www.pragma-pod.nl
-----------------------------------------------------------------

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Clipping a path to a boundary --- Being more specific
  2005-08-08 13:20 ` Hans Hagen
@ 2005-08-10  0:24   ` David Arnold
  2005-08-10 16:15     ` David Arnold
  0 siblings, 1 reply; 4+ messages in thread
From: David Arnold @ 2005-08-10  0:24 UTC (permalink / raw)


Hans et al,

I tried what follows. But as far as I can see, I am not getting back a 
path q that is clipped to the cpath.

    vardef lastpath (expr p) =
        save _p_ ; path _p_ ; _p_ := origin ;
        for i within p :
            if stroked i : _p_ := pathpart i ; fi ;
        endfor ;
        _p_
    enddef ;

    vardef firstpath (expr p) =
        save _p_, _b_ ; path _p_ ; _p_ := origin ; boolean _b_ ; _b_ := 
false ;
        for i within p :
            if not _b_ : if stroked i : _b_ := true ; _p_ := pathpart i 
; fi ; fi ;
        endfor ;
        _p_
    enddef ;


beginfig(0);

%initialize a of f(x)=|x-a|
numeric a;
a=-2;

% initialize scale
numeric u; 10u=3in;

%function definition
vardef f(expr x)=
	abs(x-a)
enddef;

%path
path F;
F:=(-5,f(-5));
for x=-5 step 1 until 5:
	F:=F--(x,f(x));
endfor;

%scale and draw F
F:=F scaled u;
draw F withcolor blue;

%clip path
path cpath;
cpath:=(5,-5)--(5,5)--(-5,5)--(-5,-5)--cycle;
cpath:=cpath scaled u;
clip currentpicture to cpath;

%save and null currentpicture
picture pic;
pic:=currentpicture;
currentpicture:=nullpicture;

%retrieve first path
path q; q:=firstpath(pic);

%draw grid
for k=-5u step 1u until 5u:
	draw (-5u,k)--(5u,k) withcolor 0.85white;
	draw (k,-5u)--(k,5u) withcolor 0.85white;
endfor;

% draw axes
drawarrow (-5u,0)--(5u,0);
drawarrow (0,-5u)--(0,5u);

% label axes
label.rt(btex $x$ etex, (5.2u,0));
label.top(btex $y$ etex, (0,5.2.u));
label.bot(btex $5$ etex, (5u,0));
label.lft(btex $5$ etex, (0,5u));

drawdblarrow q withcolor blue;

endfig;

end.

On Aug 8, 2005, at 6:20 AM, Hans Hagen wrote:

> David Arnold wrote:
>
>> Hans et al,
>>
>> Let me try to be more specific. Here is a file which is very typical 
>> of the way I draw graphs for my mathematics classes. When you 
>> compile, you will see the graph of the absolute value of x-1. That 
>> is, it draws the graph of y=|x-1|, but only after clipping it to the 
>> cpath.  What I would like to do is draw the graph with the 
>> drawdblarrow command so that the graph of the absolute value ends in 
>> arrowheads. So, I want to clip the graph to the bounding box, save 
>> the picture, null the picture, then somehow extract the path into the 
>> variable F in its clipped form (not the original path F that extends 
>> outside the clip path) so that I can replace the command draw pic 
>> with drawdblarrow F.
>
>
> hm, this need some more brainpower than the previous solution,
>
> in mp-tool there is a repathed macro that does most of the job so 
> let's extend that one a bit:
>
> \starttext
>
> \setupcolors[state=start]
>
> \startMPpage
>
> def restroke  suffix p = p := repathed (21,p) enddef ; % keep 
> attributes
> def reprocess suffix p = p := repathed (22,p) enddef ; % no attributes
>
> vardef repathed (expr mode, p) text t =
>  begingroup ;
>  if mode=0 : save withcolor ; remapcolors ; fi ;
>  save _p_, _pp_, _ppp_, _f_, _b_, _t_ ;
>  picture _p_, _pp_, _ppp_ ; color _f_ ; path _b_ ; transform _t_ ;
>  _b_ := boundingbox p ; _p_ := nullpicture ;
>  for i within p :
>    _f_ := (redpart i, greenpart i, bluepart i) ;
>    if     bounded i :
>      _pp_ := repathed(mode,i) t ;
>      setbounds _pp_ to pathpart i ;
>      addto _p_ also _pp_ ;
>    elseif clipped i :
>      _pp_ := repathed(mode,i) t ;
>      clip _pp_ to pathpart i ;
>      addto _p_ also _pp_ ;
>    elseif stroked i :
>      if mode=21 :
>        _ppp_ := i ; % indirectness is needed
>        addto _p_ also image(scantokens(t & " pathpart _ppp_")
>          dashed dashpart i withpen penpart i
>          withcolor _f_ ; ) ;
>      elseif mode=22 :
>        _ppp_ := i ; % indirectness is needed
>        addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
>      else :
>        addto _p_ doublepath pathpart i
>          dashed dashpart i withpen penpart i
>          withcolor _f_ % (redpart i, greenpart i, bluepart i)
>          if mode=2 : t fi ;
>      fi ;
>    elseif filled  i :
>      if mode=11 :
>        _ppp_ := i ; % indirectness is needed
>        addto _p_ also image(scantokens(t & " pathpart _ppp_")
>          withcolor _f_ ; ) ;
>      elseif mode=12 :
>        _ppp_ := i ; % indirectness is needed
>        addto _p_ also image(scantokens(t & " pathpart _ppp_")) ;
>      else :
>        addto _p_ contour pathpart i
>          withcolor _f_
>        if (mode=1) and (_f_<>refillbackground) : t fi ;
>      fi ;
>    elseif textual i : % textpart i <> "" :
>      if mode <> 4 :
>        addto _p_ also i if mode=3 : t fi ;
>      fi ;
>    else :
>      addto _p_ also i ;
>    fi ;
>  endfor ;
>  setbounds _p_ to _b_ ;
>  _p_
>  endgroup
> enddef ;
>
>
>    picture pic; pic := image(
>        draw fullcircle scaled 5cm withpen pencircle scaled 5mm ;
>        draw fullsquare scaled 2cm withpen pencircle scaled 5mm ;
>        fill fullcircle scaled 1cm withpen pencircle scaled 5mm ;
>    ) ;
>
>    redraw pic withpen pencircle scaled 1mm withcolor red ;
> %     restroke pic "drawdblarrow" ;
>    pic := repathed(21,pic) "drawdblarrow" ;
>    pic := repathed(11,pic) "drawdblarrow" ;
>    draw pic ;
>
> \stopMPpage
>
> \stoptext
>
> the new restroke variant takes a macro name that itself takes one 
> argument, i.e. a path, so in order to do more complex things, you need 
> to define those
> Hans
> -----------------------------------------------------------------
>                                          Hans Hagen | PRAGMA ADE
>              Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
>     tel: 038 477 53 69 | fax: 038 477 53 74 | www.pragma-ade.com
>                                             | www.pragma-pod.nl
> -----------------------------------------------------------------
>
> _______________________________________________
> ntg-context mailing list
> ntg-context@ntg.nl
> http://www.ntg.nl/mailman/listinfo/ntg-context
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Clipping a path to a boundary --- Being more specific
  2005-08-10  0:24   ` David Arnold
@ 2005-08-10 16:15     ` David Arnold
  0 siblings, 0 replies; 4+ messages in thread
From: David Arnold @ 2005-08-10 16:15 UTC (permalink / raw)


Hans et al,

I think I've found something that works. I know ahead of time that 
there will only be two crossings of the clipping path boundary (I make 
sure of the by the parameters I choose):

beginfig(0);

% initialize a, h, and h for f(x)=ax^2+bx+c=a(x-h)^2+k
numeric a, h, k;
a=-1;
h=-3;
k=2;

% initialize scale
numeric u; 10u=3in;

% draw grid
for k=-5u step 1u until 5u:
	draw (-5u,k)--(5u,k) withcolor 0.85white;
	draw (k,-5u)--(k,5u) withcolor 0.85white;
endfor;

% draw axes
drawarrow (-5u,0)--(5u,0);
drawarrow (0,-5u)--(0,5u);

% label axes
label.rt(btex $x$ etex, (5.2u,0));
label.top(btex $y$ etex, (0,5.2.u));
label.bot(btex $5$ etex, (5u,0));
label.lft(btex $5$ etex, (0,5u));

% define function f(x)=a|x-b|+c
vardef f(expr x)=
	a*(x-h)*(x-h)+k
enddef;

% draw line with given point and slope
path F;
F:=(-6,f(-6));
for x=-6 step .1 until 6:
	F:=F--(x,f(x));
endfor;

% the line
F:=F scaled 1u;

% clipping path
path cpath;
cpath:=(-5,-5)--(5,-5)--(5,5)--(-5,5)--cycle;
cpath:=cpath scaled 1u;

% clip the path F
pair A, B;
F:=F cutbefore cpath;
F:=reverse F;
F:=F cutbefore cpath;
drawdblarrow F;



endfig;

end.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-08-10 16:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-08  1:17 Clipping a path to a boundary --- Being more specific David Arnold
2005-08-08 13:20 ` Hans Hagen
2005-08-10  0:24   ` David Arnold
2005-08-10 16:15     ` David Arnold

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).