9

Glassrectangle I i

I'd like a thick Line to look like ChartElementFunction -> "GlassRectangle"

How can that be accomplished?

Gannicus
  • 126
  • 5

2 Answers2

12

Using ParametricPlot with a custom ColorFunction:

ClearAll[parametricCurve, glassGradientCF]
parametricCurve[curve_, width_][x_, u_] := curve[x] + 
    (1 - 2 u) width/2 Cross @ Normalize[curve'[x]];

glassGradientCF[color_: Red] := Module[{}, BarChart[{1}]; SystemBarFunctionDumpGlassGradient[color] @ #4]&;

Examples:

c1[x_] := {x + 1, 2 x}

pp1 = ParametricPlot[parametricCurve[c1, 1][x, u], {x, 1, 4}, {u, 0, 1}, BoundaryStyle -> Red, ColorFunction -> glassGradientCF[], Axes -> False]

enter image description here

c2[x_] := {x, Sin[x] + x/2}
pp2 = ParametricPlot[parametricCurve[c2, .5][x, u], {x, 0, 3 Pi}, {u, 0, 1},
  BoundaryStyle -> Green, ColorFunction -> glassGradientCF[Green],  Axes -> False]

enter image description here

c3[x_] := 3 {Cos @ x + 2, Sin @ x + 2}
pp3 = ParametricPlot[parametricCurve[c3, -.5][x, u], {x, 0, 3 Pi/2}, {u, 0, 1}, 
 BoundaryStyle -> Blue, ColorFunction -> glassGradientCF[Blue], Axes -> False]

enter image description here

Show[pp1, pp2, pp3, PlotRange -> All]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
  • One question though - the edges of the curved lines show little 'teeth'
    What is the best way to get a clean edge?
    – Gannicus May 15 '21 at 12:18
  • 1
    I'm using Mathematica 12.2 on Mac - I'm receiving an error msg: Blend::arg: {SystemBarFunctionDumpGlassGradient[][0],SystemBarFunctionDumpGlassGradient[][1/19],SystemBarFunctionDumpGlassGradient[] ... [8/19],SystemBarFunctionDumpGlassGradient[][9/19],<<10>>} is not a valid list of colors or images, or pairs of a real number and a color or an image. – Gannicus May 15 '21 at 12:49
  • 2
    One typo found. Instead of c2[x_] := 3 {Cos @ x + 2, Sin @ x + 2} it should read c3[x_] := 3 {Cos @ x + 2, Sin @ x + 2} – Gannicus May 15 '21 at 15:14
  • 2
    @Gannicus, corrected the typo. Modified version of glassGradientCF works in v12.2. – kglr May 15 '21 at 17:09
  • Thanks very much, it works now. Takes on a Macbook Pro 2.7GHz almost 2 minutes to run. Probably of the hi res. The teeth are pretty much gone, definitely much less than in the pics above

    One more question: How do you possibly know about 'GlassGradient' ?

    Wolfram comes up empty, ditto for Google (which already finds this contribution)

    – Gannicus May 15 '21 at 19:19
  • 1
    @Gannicus, internal chart element functions are not documented. The way I found about GlassGradient is thru a spelunking expedition: Used ClearAttributes[ChartElementDataFunction, {Protected, ReadProtected}]; ?? ChartElementDataFunction to discover that we can get the internal function that constructs the graphics primitives using ChartElementData["GlassRectangle", "InternalChartElementFunction"] (which gives System`BarFunctionDump`GlassGradientBar). Then ??System`BarFunctionDump`GlassGradientBar reveals that this function calls ... – kglr May 15 '21 at 21:25
  • 1
    ... System`BarFunctionDump`GradientBar which in turn calls System`BarFunctionDump`GlassGradient to construct a color function that gives the glass look/feel. – kglr May 15 '21 at 21:25
10

Borrowing from the technique in the glowing edges answer, you can create polygons and texture them with any image:

texturedLine[p1_, p2_, teximg_, width_] := 
  Module[{s = width, vec = p2 - p1, perp}, perp = Cross[vec];
   {Texture[teximg], 
    Polygon[{p1 - perp*s, p1 + perp*s, p2 + perp*s, p2 - perp*s}, 
     VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}];

glassTex = Import["https://i.stack.imgur.com/R6vZR.png"]; glassTex = ImageTake[glassTex, {20, 30}, {15, -15}];

Graphics[{ (* create a line from 0,0 to 1,1 with thickness .05 *) texturedLine[{0, 0}, {1, 1}, glassTex, .05],

(* create lots of lines around a circle *) texturedLine[#[[1]], #[[2]], glassTex, .3] & /@ Partition[CirclePoints[50], 2, 1] }]

glass textured lines

flinty
  • 25,147
  • 2
  • 20
  • 86
  • Excellent, thanks much! – Gannicus May 15 '21 at 05:49
  • Flinty - when I reduce Circlepoints to say 10, it becomes visible that it's a bunch of rectangles (which is what I asked for )

    Is there an easy way to map such a rectangle to a sector of a circle. Or to a segment of a ring when mapping to a function such as sin x?

    – Gannicus May 15 '21 at 19:27