All the code:
Viewing polyhedron
SetDirectory[NotebookDirectory[]];
$HistoryLength = 2;
ClearAll[RefineSphere]
RefineSphere[{fi_, vc_}] :=
Module[{vcc, max = Max[fi], nfi, avgs, midpoints, newtriangles,
newvc},
vcc = DeleteDuplicates[
Sort /@ Flatten[Subsets[#, {2}] & /@ fi, 1]];
nfi = MapThread[Rule, {vcc, max + Range[Length[vcc]]}];
avgs = Mean[vc[[#]]] & /@ vcc;
newvc = Normalize /@ (vc~Join~avgs);
midpoints = Partition[#, 2, 1, 1] & /@ fi;
newtriangles =
MapThread[
Append[Flatten[#,
1] & /@ ({#2,
Partition[Sort /@ RotateRight[#1], 2, 1, 1]}\[Transpose]),
Sort /@ #1] &, {midpoints, fi}];
newtriangles = Flatten[Replace[newtriangles, nfi, {3}], 1];
{newtriangles, newvc}
]
refine = 0
sphereFI = PolyhedronData["Icosahedron", "FaceIndices"];
sphereVC = N@PolyhedronData["Icosahedron", "VertexCoordinates"];
{sphereFI, sphereVC} =
Nest[RefineSphere, {sphereFI, sphereVC}, refine];
sphereVC *= 40;
Graphics3D[GraphicsComplex[sphereVC, Polygon[sphereFI]],
Lighting -> "Neutral"]
Vectors
size = 600; (* each view will be rendered this size squared *)
vangle = 80 \[Degree]; (* view angle is 80\[Degree] *)
(* calculate the various viewing angles *)
viewvectorup =
viewvectors = Normalize[Mean[Part[sphereVC, #]]] & /@ sphereFI;
crosslen = (Norm /@ viewvectors) Tan[vangle/2];
viewvectorup =
Normalize[{0, 0, 1} - ({0, 0, 1}.Normalize[#]) Normalize[#]] & /@
viewvectorup;
viewvectorup *= crosslen;
viewvectorright =
MapThread[Normalize@*Cross, {viewvectors, viewvectorup}];
viewvectorright *= crosslen;
(* make black-white masks for each view, note that we use 0.96 \
viewing angle here such that each of the views overlaps a bit *)
masks = MapThread[
Rasterize[
Graphics3D[{EdgeForm[], White,
GraphicsComplex[sphereVC, Polygon[#1]]}, Boxed -> False,
Lighting -> "Neutral", ViewVertical -> {0, 0, 1},
ViewVector -> {{0, 0, 0}, #2}, ViewAngle -> (0.96 vangle),
ImageSize -> {size, size}, Background -> None], "Image",
Background -> None] &, {sphereFI, viewvectors}];
(* this is what all the viewingvectors look like (blue), green is the \
pointing-up vector, and in red is the vector to the right *)
gr =
Graphics3D[
MapThread[{Blue, Arrow[Tube[{{0, 0, 0}, #1}]], Green,
Arrow[Tube[{#1, #1 + #2}]], Red,
Arrow[Tube[{#1, #1 + #3}]]} &, {viewvectors, viewvectorup,
viewvectorright}]]
Functions
vvv = {viewvectors, viewvectorright, viewvectorup}\[Transpose];
normvvv = Map[Normalize, vvv, {2}];
nvvv = Map[Norm, vvv, {2}];
svv = vvv/nvvv^2;
ClearAll[invtransfunc];
invtransfunc[{\[Phi]_, \[Theta]_}, n_] := Module[{vp},
vp = {Cos[\[Phi]] Sin[\[Theta]], Sin[\[Theta]] Sin[\[Phi]],
Cos[\[Theta]]};
If[vp.vvv[[n, 1]] <= 0,
vp = (vp nvvv[[n, 1]]/(vp.normvvv[[n, 1]]));
{vp.svv[[n, 2]], vp.svv[[n, 3]]}
,
{-2, -2}
]
];
ClearAll[MakeScene]
MakeScene[t_] := Module[{rot, p1, p2},
rot = 2 \[Pi] t;
p1 = ParametricPlot3D[{-8.2 + (8 + Cos[v]) Sin[u + t], (8 +
Cos[v]) Cos[u + t], Sin[v] + 0.75}, {u, 0, 2 Pi}, {v, 0,
2 Pi}, ViewVector -> {{0, 0, 0}, {0, 1, 0}},
ViewAngle -> 80 \[Degree],
PlotStyle -> Directive[Green, Opacity[1]],
MeshShading -> {{Red, Blue}, {Blue, Red}},
MeshFunctions -> {#4 &, #5 &}, PlotPoints -> 80, Axes -> False,
Mesh -> {51, 10}, Lighting -> {{"Ambient", White}},
ViewVertical -> {0, 0, 1}];
p2 = Graphics3D[{Orange,
Sphere[{-8.2 - 8 Sin[2 rot], 8 Cos[2 rot], 0.45}, 0.2]},
Lighting -> {{"Ambient", White}}];
Show[{p1, p2}]
]
ClearAll[Make360]
Make360[scenef_, t_] :=
Module[{scn, views, antetransform, posttransform, \[Alpha]cs, imgout},
\[Beta]++;
scn = scenef[t];
views = MapThread[
Rasterize[
Show[scn, ViewVector -> {{0, 0, 0}, #1},
ViewVertical -> {0, 0, 1}, ViewAngle -> vangle, Boxed -> False,
ImageSize -> {size, size}, Background -> White],
"Image"] &, {viewvectors}];
antetransform = MapThread[ImageMultiply, {masks, views}];
posttransform =
Table[ImageTransformation[antetransform[[n]], invtransfunc[#, n] &,
DataRange -> {{-1, 1}, {-1, 1}},
PlotRange -> {{-\[Pi], \[Pi]}, {0, \[Pi]}},
Padding -> Transparent]
,
{n, Length[antetransform]}
];
\[Alpha]cs = AlphaChannel /@ posttransform;
posttransform = RemoveAlphaChannel /@ posttransform;
\[Alpha]cs = Binarize[#, 0.95] & /@ \[Alpha]cs;
posttransform =
MapThread[SetAlphaChannel, {posttransform, \[Alpha]cs}];
imgout = ImageCompose[First[posttransform], Rest[posttransform]];
imgout = RemoveAlphaChannel[imgout];
imgout
]
Calculation/Rendering/Export
SetDirectory[NotebookDirectory[]];
Dynamic[\[Beta]]
\[Beta] = 0;
n = 150;
t = Most[Subdivide[0, 1, n]];
fns = "out" <> ToString[#] <> ".png" & /@ Range[Length[t]];
CloseKernels[];
LaunchKernels[4];
DistributeDefinitions[Make360, MakeScene, n, t, fns, i, vvv, normvvv,
svv, nvvv, invtransfunc, masks, size, vangle, viewvectors,
viewvectorright, viewvectorup, sphereFI, sphereVC];
SetSharedVariable[\[Beta]];
ParallelEvaluate[$HistoryLength = 2];
ParallelDo[
If[! FileExistsQ[fns[[i]]],
out = Make360[MakeScene, t[[i]]];
Export[fns[[i]], out];
]
,
{i, 1, Length[fns]}
,
Method -> "FinestGrained"
]
Attachments: