Yet another method:
Let us calculate values of function on appropriate rectangular grids, which we will convert to textures (1 pixel = 1 value). Interpolation between pixels is built-in.
f = 2 #1^2 + 2 #2^2 + #3^2 + #1 #2 &;
PolyhedronData["Cube"] // N // Normal // toTriangles //
texturize[f, 50, Hue, Lighting -> "Neutral", Axes -> True]
Here Normal
convert GraphicsComplex
to separate polygons, toTriangles
split polygons to triangles, and texturize
put textures on every triangle (f
assumed to be Listable
)
toTriangles = # /. Polygon[v_ /; Length[v] > 3] :> (Polygon@Append[#, Mean[v]] & /@
Partition[v, 2, 1, 1]) &;
texturize[f_, n_, colf_, opts : OptionsPattern[]] := # /.
Polygon[{v1_, v2_, v3_}] :> {EdgeForm[],
Texture@ImageData@Colorize[Image@
f[v3[[1]] + (v1[[1]] - v3[[1]]) #1 + (v2[[1]] - v3[[1]]) #2,
v3[[2]] + (v1[[2]] - v3[[2]]) #1 + (v2[[2]] - v3[[2]]) #2,
v3[[3]] + (v1[[3]] - v3[[3]]) #1 + (v2[[3]] - v3[[3]]) #2] &
[#, Transpose[#]] &@
ConstantArray[Range[-1./n, 1 + 1/n, 1./n], n + 3],
ColorFunction -> colf, ColorFunctionScaling -> False],
Polygon[{v1, v2, v3}, VertexTextureCoordinates -> {{1 - 1.5/(n+3), 1 - 1.5/(n+3)},
{1.5/(n+3), 1.5/(n+3)}, {1.5/(n+3), 1 - 1.5/(n+3)}}]} /.
Graphics3D[data__] :> Graphics3D[data, opts] &;
It is really fast because it uses packed arrays (almost 100 times faster the belisarius's rasterization of DensityPlot
)!
Moreover, it is applicable to arbitrary complex mesh:
PolyhedronData["MathematicaPolyhedron"] // N // Normal // toTriangles //
texturize[0.7 (#1^2 + #2^2 + #3^2) &, 50, Hue, Lighting -> "Neutral", Boxed -> False]
To obtain "contours" one can use simple discretization with bigger number of points (sometimes it can be faster then ContourPlot
):
f = Floor[2 #1^2 + 2 #2^2 + #3^2 + #1 #2, .1] &;
PolyhedronData["Cube"] // N // Normal // toTriangles //
texturize[f, 200, Hue, Lighting -> "Neutral", Axes -> True]
The same with the simple cut
Graphics3D[
GraphicsComplex[
Tuples[{-0.5, 0.0, 0.5}, 3], {Polygon[{1, 3, 9, 7}],
Polygon[{1, 3, 21, 19}], Polygon[{1, 7, 25, 19}],
Polygon[{19, 21, 24, 23}], Polygon[{19, 25, 26, 23}],
Polygon[{7, 25, 26, 17}], Polygon[{7, 9, 18, 17}],
Polygon[{3, 9, 18, 15}], Polygon[{3, 21, 24, 15}],
Polygon[{23, 14, 15, 24}], Polygon[{23, 14, 17, 26}],
Polygon[{15, 14, 17, 18}]}]] // N // Normal // toTriangles //
texturize[f, 100, Hue, Lighting -> "Neutral", Axes -> True]
SliceContourPlot3D
andSliceDensityPlot3D
which provide functionality to plot values on arbitrary surfaces. $\endgroup$