PSTricks 中 \psline 的颜色渐变

PSTricks 中 \psline 的颜色渐变

我想在 PSTricks 中生成一个\psline(或者更好的是\pscurve),它具有颜色渐变。我找不到允许我这样做的包。有吗?(pst-slpe为区域生成复杂的渐变,但据我所知,不为线条生成。)

(在页面上https://comp.text.tex.narkive.com/tjLnOyJ4/applying-a-gradient-color-to-a-lineWerner 报告说,他在 2003 年在 PSTricks 邮件列表中问过同样的问题,并收到了 Manuel Luque 的回复,其中定义了一个(复杂的)函数来创建带有颜色渐变的参数图。将该代码改编为 似乎并不容易\psline。)

答案1

运行lualatex

\documentclass{standalone}
\usepackage{pst-hsb}
\begin{document}

\begin{pspicture}(-0.75,-0.75)(11,5)
% \psgrid(0,-4)(10,4)
\psaxes{->}(0,0)(11,5)   
\pslineHSB[linewidth=1mm,HueBegin=0,HueEnd=0.5](0,0)(10,1) 
\pslineHSB[linewidth=1mm,HueBegin=0.5,HueEnd=0.7](0,1)(10,3) 
\pslineHSB[linewidth=1mm,HueBegin=0.8,HueEnd=1](0,2)(10,5) 
\end{pspicture}

\end{document}

在此处输入图片描述

或者只针对两种给定的颜色。也许这将是 PSTricks 更新的一部分...

\documentclass{article}
\usepackage{pstricks-add}
\makeatletter
\define@key[psset]{pstricks}{startColor}[black]{%
  \colorlet{tempcolor}[rgb]{#1}%   we need rgb
  \pst@getcolor{tempcolor}\ps@startColor}
\define@key[psset]{pstricks}{endColor}[white]{%
  \colorlet{tempcolor}[rgb]{#1}%
  \pst@getcolor{tempcolor}\ps@endColor}
\psset[pstricks]{startColor=black,endColor=white}

\def\pscolorLine{\def\pst@par{}\pst@object{pscolorLine}}
\def\pscolorLine@i{%
  \pst@getarrows{%
    \begin@OpenObj
    \pscolorLine@ii}}
    
\def\pscolorLine@ii(#1){\@ifnextchar({\pscolorLine@iii(#1)}{\pscolorLine@iii(0,0)(#1)}}%

\def\pscolorLine@iii(#1,#2)(#3,#4){%
  \use@par
  \ifx\psk@arrowA\@empty\else\psline[linecolor=\ps@startColor]{->}(!#3 0.5 mul #4 0.5 mul)(#1,#2)\fi
  \ifx\psk@arrowB\@empty\else\psline[linecolor=\ps@endColor]{->}(!#1 0.5 mul #2 0.5 mul)(#3,#4)\fi
  \pst@getcoor{#1,#2}\pst@tempA
  \pst@getcoor{#3,#4}\pst@tempB
  \addto@pscode{
    10 dict begin
    [ \psgetRGBColorValues{\ps@startColor} ] dup == aload length 1 eq { dup dup } if 
      3 copy 3 array astore /startColor ED
    [ \psgetRGBColorValues{\ps@endColor} ] dup == aload length 1 eq { dup dup } if 
      3 copy 3 array astore /endColor ED
%   on stack R1 G1 B1 R2 G2 B2 
    4 -1 roll               % R1 G1 R2 G2 B2 B1
    sub 256 div /dB ED      % R1 G1 R2 G2 
    3 -1 roll               % R1 R2 G2 G1 
    sub 256 div /dG ED      % R1 R2 
    exch sub 256 div /dR ED
    \pst@tempB /Y2 ED /X2 ED 
    \pst@tempA /Y1 ED /X1 ED 
    Y2 Y1 sub X2 X1 sub atan /Angle ED
    Y2 Y1 sub Angle sin dup 0 eq { pop }{ div } ifelse /L_line ED     % line length
    \ifx\psk@arrowA\@empty\else 
      X2 X1 sub L_line div \psk@arrowlength\space mul \pst@number\psxunit mul X1 add /X1 ED
      Y2 Y1 sub L_line div \psk@arrowlength\space mul \pst@number\psyunit mul Y1 add /Y1 ED
     \fi
    \ifx\psk@arrowB\@empty\else 
      X2 X1 sub L_line div \psk@arrowlength\space mul \pst@number\psxunit mul X2 exch sub /X2 ED
      Y2 Y1 sub L_line div \psk@arrowlength\space mul \pst@number\psyunit mul Y2 exch sub /Y2 ED
     \fi
    Y2 Y1 sub 256 div /dY ED
    X2 X1 sub 256 div /dX ED
%    dR dG dB == == ==
%startColor == endColor ==
    \ifPst@noCurrentPoint\else\pst@cp\fi      % current point?
    0 1 255 {      
      /dIndex ED
%startColor == 
      X1 Y1 moveto
      X1 dX add  Y1 dY add % start for coordinate array
      gsave
      lineto
      CP /Y1 ED /X1 ED
      \pst@number\pslinewidth SLW
      startColor aload pop 3 copy setrgbcolor
      % on stack r g b
      dB add 3 1 roll    % b+dB r g 
      dG add 3 1 roll    % b+dB g+dG r
      dR add 3 1 roll    % b+dB g+dG r+dR
      3 array astore /startColor ED
      stroke
      grestore
    } for 
    end
  }%
  \end@OpenObj
  \ignorespaces
}

\makeatother

\begin{document}

\begin{pspicture}[linewidth=12pt,showgrid](-5,-5)(5,5)
\pscolorLine(0,-5)(0,5)
\pscolorLine[startColor=cyan,endColor=magenta](-5,0)(5,0)
\pscolorLine[startColor=blue,endColor=green]{->}(-5,5)(5,-5)
\pscolorLine[startColor=red,endColor=blue]{<->}(-5,-5)(5,5)
\end{pspicture}

\end{document}

在此处输入图片描述

答案2

在你等待 PStricks 帮助的时候,我尝试元帖子解决方案,以供比较。

在此处输入图片描述

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
vardef cgdraw(expr P, a, b) = 
    save s, n; 
    numeric s, n;
    4s = xpart urcorner currentpen - xpart llcorner currentpen;
    n = arclength P / s;
    for i=0 upto n:
        draw point arctime s * i of P of P withcolor (i/n)[a, b];
    endfor
enddef;
beginfig(1);
    path p; p = origin .. (89, 34) .. (144, -13) .. (200, 0);
    cgdraw(p, red, blue);
endfig;
\end{mplibcode}
\end{document}

这被包装在 中luamplib,因此请使用 进行编译lualatex

它的工作原理很简单,只需沿路径绘制点即可。您可以使用相同的方法来减小线条的宽度,例如,通过将循环中的线条更改为

draw point arctime s * i of P of P withpen currentpen scaled (1-i/n);

这将给你这个

在此处输入图片描述

  • 请注意,drawMP 中的单个点只需使用当前笔在该点处绘制一个点。(与 相同drawdot)。

相关内容