6

I would like to draw a line or curve and blur it partially or gradually. AFAIK Blurring is only blurring for a complete object (like a line). Of course I can clumsily split a line in chunks like below but it's not very useful. Any ideas?

b = BezierFunction[{{0, 0}, {1, 1}, {2, 0}, {5, 5}}]
xy = Flatten[
   MapIndexed[{Blurring[ First@#2/10 - 1], Line[#1]} &, 
    Partition[Table[b[x], {x, 0, 1, 0.02}], 2, 1]], 1];
Graphics[{Thick, Green, xy}]

enter image description here

MarcoB
  • 67,153
  • 18
  • 91
  • 189
Lou
  • 3,822
  • 23
  • 26
  • Can you be more precise why your method is not very useful? It looks like it's working ... – Domen Aug 14 '23 at 15:35
  • @Domen He wants the blurring delta to be continuous – user5601 Aug 14 '23 at 16:08
  • 1
    CapForm["Round"] seems to do the best job, but it's not perfect (I think). -- Too bad Blurring[] does not work with VertexColors (feature request!). – Michael E2 Aug 14 '23 at 16:40
  • 3
    Not bad, but slow: b = BezierFunction[{{0, 0}, {1, 1}, {2, 0}, {5, 5}}] xy = Flatten[ MapIndexed[{Blurring[First@#2/100 - 1], Line[#1]} &, Partition[Table[b[x], {x, 0, 1, 0.002}], 2, 1]], 1]; Graphics[{Thick, Red, CapForm["Butt"], xy}] – Michael E2 Aug 14 '23 at 16:42
  • I wonder if OP might be looking for something more like the answer that currently uses Opacity to emulate the Blurring effect that they envision. I mention this because they have made comments of wanting the line to stay the same thickness, and also have a worry how some solutions will work with multiple lines. As far as I understand, a true Blurring would not satisfy well either of those concerns. – CA Trevillian Aug 16 '23 at 00:57
  • 1
    @CATrevillian yes perhaps I should have been more clear. I was focussed on blurring but the Opacity is closer to what I need. I see many nice methods are presented! – Lou Aug 16 '23 at 13:33

4 Answers4

8

Here is a possible approach using overlapping lines

b = BezierFunction[{{0, 0}, {1, 1}, {2, 0}, {5, 5}}];
curves = Table[n b[x], {n, 0.9, 1.1, .01}];
styles = Table[{Blue, Opacity[n]}, {n, .01, .4, .04}];

ParametricPlot[curves, {x, 0, 2}, PlotStyle -> Join[styles, {{Blue, Opacity[0.4]}}, Reverse[styles]]]

enter image description here

MelaGo
  • 8,586
  • 1
  • 11
  • 24
6

I will happily delete this if it's not really what you're looking for, but you could convert the plot to an image and then blur with increasingly large kernel Gaussian filters:

b = BezierFunction[{{0, 0}, {1, 1}, {2, 0}, {5, 5}}]
p = ParametricPlot[b[t], {t, 0, 1}, Axes -> False]

enter image description here

img = Import["https://i.stack.imgur.com/hHgov.png"]
gF[i_, ker_] := GaussianFilter[i, ker]
takeParts = 
 Table[ImageTake[img, {1, 720}, {(36*(x - 1) + 1), 36*x}], {x, 20}];
blurred = Table[gF[takeParts[[x]], x/2], {x, Length@takeParts}]
ImageAssemble[blurred]

enter image description here

ydd
  • 3,673
  • 1
  • 5
  • 17
  • 1
    thx. I would prefer a graphic approach instead of image. That said I like this approach but wonder how it would work with many closely aligned lines etc. – Lou Aug 14 '23 at 18:07
5

Not blurring but maybe close enough to what you want. We create a parametric function from the bezier curve via this question and apply a color function. Feel free to experiment with it. Potentially you can combine it with this question to make the function wider and use the opacity of the color function to achieve a similar effect.

Clear[points, b, p]
points = {{0, 0}, {1, 1}, {2, 0}, {5, 5}};
b = BezierFunction[points];
p[t_] := Sum[points[[i + 1]] BernsteinBasis[3, i, t], {i, 0, 3}];
ParametricPlot[p[t], {t, 0, 1}, 
 ColorFunction -> (Hue[0.3, 1, 1, Max[1 - #, 0.1]] &)]

enter image description here

infinitezero
  • 1,419
  • 8
  • 18
  • I think this is closest to what I meant indeed. I now need to figger out what the BernsteinBasis is.. – Lou Aug 16 '23 at 13:36
5

Following a similar approach to kglr's (now deleted) answer, just with different choices of ColorFunction et al.:

width = 0.1;
parallel[t_, d_] := b[t] - d Cross[b'[t]]/Norm[b'[t]]
ParametricPlot[parallel[t, d], {t, 0, 1}, {d, - width , width}, 
 ColorFunction -> 
  Function[{x, y, u, v}, 
   Directive[
    Opacity[(1.5 - u) Exp[-(v - 1/2)^2/(2 (u + 0.1) width)^2]]]], 
 BoundaryStyle -> None]

enter image description here

Michael Seifert
  • 15,208
  • 31
  • 68