我想在 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);
这将给你这个
- 请注意,
draw
MP 中的单个点只需使用当前笔在该点处绘制一个点。(与 相同drawdot
)。