Community RSS Feed
https://community.wolfram.com
RSS Feed for Wolfram Community showing any discussions in tag Staff Picks sorted by active[MAKE] Spikey Commemorative Coins
https://community.wolfram.com/groups/-/m/t/1569688
**Authors : [@Frederick Wu][at0] [@Shenghui Yang][at1]**
![enter image description here][414]
![enter image description here][415]
![enter image description here][1]
![enter image description here][416]
One day my friend ShengHui Yang from Wolfram Alpha approached me and suggested that I could make a physical Wolfram Spikey Coin (not to confuse with [Wolfram Blockchain Token][2] ;-) ), as for [the celebration for the 30th anniversary of Mathematica][3]. As a long-term Mathematica user and coin collector, I challenged myself to design my own commemorative coin for such a special event.
![enter image description here][4]
The iconic [Spikey][5] is a life-long companion of Mathematica since Version 1, coined (no pun intended) in 1988. We come to a time that [Wolfram technologies][6] and different 3D Printing processes happily marry together in 2018.
1. Introduction
------------
Traditional coin casting is [low-relief][11] design. It is the optical orthogonal projection that makes viewers feel the sculpture raised from the background plane and creates a vivid 3D optical illusion with minimum model depth. Usually, the relief depth plane can be set between front plane of the object and the vanishing plane. A low-relief compresses the model in axial direction (perpendicular to the background plane) in the scale ratio ranging from 0.02 to 0.1, a high relief from 0.1 to 0.2, and a super-high-relief greater than 0.3.
![enter image description here][12]
I crafted a Demonstration Projects Applet ([Design Your Own Commemorative Coin][13]) to illustrate some cool coin designs using aforementioned orthogonal projection and 3D geometric scaling method. The user can freely set the view point, the level of relief plane and the scaling ratio.
Here there is a list of geometric objects available in the applet:
subjectList = {"Spikey", "BassGuitar", "Beethoven", "CastleWall",
"Cone", "Cow", "Deimos", "Galleon", "HammerheadShark", "Horse",
"KleinBottle", "MoebiusStrip", "Phobos", "PottedPlant", "Seashell",
"SedanCar", "SpaceShuttle", "StanfordBunny", "Torus", "Tree",
"Triceratops", "Tugboat", "UtahTeapot", "UtahVWBug", "Vase",
"VikingLander", "Wrench", "Zeppelin"};
Here there is a list of materials and colors available. The texture of the metal affects the reflection and color of the coin:
material = {"Pt", "Au", "Ag", "Cu", "Ni", "Ti", "Al", "Zn"};
color = ColorData["Atoms"][#] & /@ material;
materialColor =
Thread[Rule[color,
Row[{#[[1]], " ", #[[2]]}] & /@ Transpose[{material, color}]]];
Extract the 3D body configuration of the Spikey through ExampleData.
modelFun[object_] :=
If[object == "Spikey", PolyhedronData["Spikey", "GraphicsComplex"],
ExampleData[{"Geometry3D", object}, "GraphicsComplex"]];
Create 3D models of coins and add controls to the applet:
![enter image description here][14]
Programming in Wolfram Language provides a simple way to evaluate the accuracy of a relief model against a real 3D model. Think about the test as if you handhold a solid 3D spikey and rotate it so the spikey can coincide with the configuration in the relief above. Meanwhile the scaling effect is how close you hold the spikey to your eye.
What we mean about same configuration is that the grey impression on the left was as if made by the right object punching through the round piece. Like aligning a palm with the impression after a face slap.
![enter image description here][15]
To quantify the scaling effect, run the following code to generate three pieces of graphical information:
region3DRaw = PolyhedronData["Spikey", "Region"];
region3D =
TransformedRegion[region3DRaw, RotationTransform[3, {1, 1, 1}]];
region3DTr =
TransformedRegion[region3D,
ScalingTransform[.2, {0, 0, 1}, {0, 0, 0}]];
- The left graphics is a view of a real 3D spikey object (2D
projection onto our retina).
- The middle one is a relief model from same view point but the model is "squeezed" (moved back and forth) with a certain scaling ratio along
a certain vector. The vector is in the direction of a given view point and center of the object.
- The right image is the image difference between the 3D object and the relief object.
It counts difference pixels in image range.
SetOptions[{Region}, Boxed -> False, ViewPoint -> {0, 2, 10},
BaseStyle -> {Gray, EdgeForm[Thick]},
PlotRange -> {{-2, 2}, {-2, 2}, {-2, 2}}, AspectRatio -> 1,
Lighting -> {"Directional", White}, ImageSize -> 400 {1, 1}];
threeDim = Region[region3D];
reliefDim = Region[region3DTr];
Export["threeDim.png", threeDim];
Export["reliefDim.png", reliefDim];
imageThreeDim = Import["threeDim.png"];
imageRelief = Import["reliefDim.png"];
diff = Binarize@ImageDifference[imageThreeDim, imageRelief];
Grid[{Style[#, 14] & /@ {"real 3D object", "relief model",
"image pixel difference"},
Framed /@ {imageThreeDim, imageRelief, ColorNegate@diff}}]
![enter image description here][16]
Further numerical analysis can be carried out with the code below, shown in the list plot on the left and right contour shown numerically.
On the right graph, for example, we choose a red point on the cross:
- A 3D model compressed at scaling ratio 0.2 and becoming a relief
model.
- An observer views the relief model within a view angle range, deviated
from the center vector less than 10 degrees.
It generates only 3.3% pixel error in boundary. In other words, the relief model used 20% depth of the 3D object to create 96.7% 3D effect.
![enter image description here][17]
2. Design
---------
We have come a long way, but the job is not finished yet. There is small clearance between the spikey and coin body. So I need to fill the gap in geometry.
First, I get the spikey region model, I also rotate the Spikey a little bit to create a non-symmetric pattern for artistic reasons.
SetOptions[{Region}, Boxed -> False, ViewPoint -> Automatic,
BaseStyle -> {Pink, EdgeForm[Thick]},
PlotRange -> All, AspectRatio -> 1, Lighting -> "Neutral",
ImageSize -> 400 {1, 1}];
SpikeyRegion = PolyhedronData["Spikey", "Region"];
SpikeyRegion3D =
TransformedRegion[
TransformedRegion[SpikeyRegion, RotationTransform[E, {E, Pi, E}]],
ScalingTransform[12 {1, 1, 1}, {0, 0, 0}]];
Row[{Column[{"Spikey Top View",
Region[SpikeyRegion3D, ImageSize -> 250 {1, 1},
ViewPoint -> {0, 0, 100}]}, Alignment -> Center],
Column[{"Spikey Bottom View",
Region[SpikeyRegion3D, ImageSize -> 250 {1, 1},
ViewPoint -> {0, 0, -100}]}, Alignment -> Center]}]
![enter image description here][21]
Here I pull each face of the triangle or polygon along the Z direction.
regionData = Table[MeshPrimitives[SpikeyRegion3D, i], {i, 0, 2}];
transGroup =
Table[Table[
Map[(# + {0, 0, i}) &, regionData[[3]][[j]][[1]]], {i, 0, 50,
50}], {j, Length@regionData[[3]]}];
I use ConvexHull to generate prism-like polyhedrons from each triangle.
Grid@Partition[
Take[convexhullMesh = ConvexHullMesh[Flatten[#, 1]] & /@ transGroup,
16], 8]
![enter image description here][22]
Now, I use RegionUnion to join all generated prism-like polyhedrons together, It becomes a pulled long Spikey, but without changing the front and back side geometry.
regionUnion1 =
Table[BoundaryDiscretizeRegion[
RegionUnion @@ Take[convexhullMesh, {3 (i - 1) + 1, 3 (i)}]], {i,
1, 20}];
regionUnion2 =
Table[RegionUnion @@ Take[regionUnion1, {5 (i - 1) + 1, 5 i}], {i,
4}];
convexhullUnion =
RegionUnion[RegionUnion[regionUnion2[[1]], regionUnion2[[4]]],
RegionUnion[regionUnion2[[2]], regionUnion2[[3]]]]
![enter image description here][23]
Below I use RegionProduct to prepare a coin body with an outside protective ring.
regularPolygonMesh[r_Integer, n_Integer] :=
BoundaryMeshRegion[
Table[r {Cos[k 2 \[Pi]/n], Sin[k 2 \[Pi]/n]}, {k, n}],
Line[Append[Range[n], 1]]];
r1 = 21;
r2 = 23;
h1 = 25 + 41.5;
h2 = 25 - 41.5;
annulus =
RegionDifference[regularPolygonMesh[r2, 2*64],
regularPolygonMesh[r1, 2*64]];
line = Line[{{h2}, {h1}}];
tube = BoundaryDiscretizeRegion[RegionProduct[annulus, line]];
d1 = 25 - 7.5;
d2 = 25 + 7.5;
bottomPlate =
BoundaryDiscretizeRegion[
RegionProduct[regularPolygonMesh[r2, 2*64], Line[{{d1}, {d2}}]]];
assembly = RegionUnion[bottomPlate, tube]
![enter image description here][24]
Then I compress the 3D pulled Spikey into a relief model and export STL file for 3D printing. This transformation process takes about 10 seconds to complete.
![enter image description here][25]
Printout3D[SpikeyRelief, "SpikeyRelief" <> ".stl",
RegionSize -> Quantity[40, "Millimeters"]]
![enter image description here][26]
Similarly, we compress the 3D pulled coin into a coin model and export STL file for 3D printing. Later I will join the relief model and the coin model together. Usually, the coin ring is a little bit thicker than the relief height, so that the outside ring can protect the relief patterns and resist abrasion.
Coin = TransformedRegion[assembly,
ScalingTransform[0.03, {0, 0, 1}, {0, 0, 0}]]
![enter image description here][27]
Printout3D[Coin, "Coin" <> ".stl",
RegionSize -> Quantity[46, "Millimeters"]]
![enter image description here][28]
3. Visualizing
--------------
Let's take a glance at the whole model. The concept of coin design is **"Breakthrough"** or **"Penetration"**. It looks like, the spikey breaks or travels through a coin plate in space and time.
convexhullData =
MeshPrimitives[ConvexHullMesh[Flatten[#, 1]], 2] & /@ transGroup;
Graphics3D[{convexhullData, Opacity[.5], Red,
Cylinder[{{0, 0, 25 - 8}, {0, 0, 25 + 8}}, r1],
Blue, Opacity[.2], EdgeForm[None], MeshPrimitives[tube, 2]},
Axes -> True, ImageSize -> {600, 400}]
![enter image description here][31]
Set scale ratio is 0.025, and compress the 3D model into the relief model.
scale = 0.025;
subject =
GeometricTransformation[{convexhullData},
ScalingTransform[scale, {0, 0, 1}, {0, 0, 0}]];
body = GeometricTransformation[{Cylinder[{{0, 0, 25 - 7.5}, {0, 0,
25 + 7.5}}, r1]},
ScalingTransform[scale, {0, 0, 1}, {0, 0, 0}]];
ring = GeometricTransformation[{MeshPrimitives[tube, 2]},
ScalingTransform[scale, {0, 0, 1}, {0, 0, 0}]];
coin3D = Graphics3D[{ EdgeForm[None], ColorData["Atoms"]["Au"],
subject, White, body, ring }, Lighting -> Red, Boxed -> False,
ImageSize -> 400 {1, 1}]
![enter image description here][32]
vp = {{0, -Infinity, 0}, {-Infinity, 0, 0}, {0, 0, Infinity}, {0,
0, -Infinity}, {-1, -.1, 2}, {-1, -.1, -2}};
Grid[Partition[Table[
Graphics3D[{EdgeForm[None], Specularity[Brown, 100],
ColorData["Atoms"]["Cu"], subject,
LightBlue, Specularity[Red, 100], body,
Opacity[If[i == 1 || i == 2, .01, 0.9]], ring},
Axes -> If[i <= 4, True, False], Boxed -> If[i <= 4, True, False],
PlotRange -> Automatic,
AxesLabel -> (Style[#, 12, Bold] & /@ {"x", "y", "z"}),
ImageSize ->
Which[i == 1, {300, 100}, i == 2, {300, 100},
i == 3, {300, Automatic}, i == 4, {300, Automatic},
i == 5, {300, Automatic}, i == 6, {300, Automatic}],
ViewPoint -> vp[[i]]], {i, 1, Length@vp}], 2], Spacings -> 5]
![enter image description here][33]
As the concept of "Breakthrough" or "Penetration", the spikey should go through a coin plate. The two sides of the coin pattern (obverse and reverse) look similar, but they are not exactly the same. They are the front view {0, 0, Infinite} and the back view {0, 0, -Infinite} of the same Spikey.
Column[Row[{Column[{Style["Spikey Coin, Obverse, " <> #[[2]], 20],
Graphics3D[{EdgeForm[None], Specularity[#[[1]], 50],
ColorData["Atoms"][#[[2]]], subject, White, body, ring},
Boxed -> False, ViewPoint -> {-1.5, -2, 10},
ViewAngle -> Pi/30, Background -> Black,
ImageSize -> 300 {1, 1}]}, Alignment -> Center],
Column[{Style["Spikey Coin, Reverse, " <> #[[2]], 20],
Graphics3D[{EdgeForm[None], Specularity[#[[1]], 50],
ColorData["Atoms"][#[[2]]], subject, White, body, ring},
Boxed -> False, ViewPoint -> {-1.5, -2, -10},
ViewAngle -> Pi/30, Background -> Black,
ImageSize -> 300 {1, 1}]}, Alignment -> Center]
}] & /@ {{Brown, "Cu"}, {White, "Ag"}, {Yellow, "Au"}}]
![enter image description here][34]
4. 3D Printing and Prototypes
-----------------------------
**4.0 3D Model Quality**
My very first printed sample was bad. It was a Graphics3D-based model, so it has all faces glued together.
![enter image description here][41]
Then, I struggled to improve the model quality, move them into region-generated, discretization and defects should be checked and passed.
![enter image description here][42]
**4.1 FDM (Fused Deposition Modeling)**
FDM (Fused Deposition Modeling) is most widely used 3D printing technology works with thermoplastics at low cost, but it also has a relatively low accuracy.
![enter image description here][43]
![enter image description here][44]
I set the model in horizontal placement for high relief coin. It looks OK. But for low relief and thin parts, I later changed the placement to vertical or tilted attitude.
![enter image description here][45]
![enter image description here][46]
![enter image description here][47]
**4.2 SLA (Stereo-lithography)**
SLA (Stereo-lithography) is also 3D printing technology by using ultraviolet light to cure photosensitive polymers. Its advantage is that it has a higher accuracy in comparison to FDM.
![enter image description here][48]
![enter image description here][49]
If many Spikey 3D models and Spikey coins are printed together, they look like a square of Spartan warriors holding sharp spears and shields.
![enter image description here][410]
**4.3 MP (Metal Powder)**
Metal powder is a 3D printing process with a high accuracy and high cost, it is like a powder bed fusion and directed energy deposition grew at an explosive pace.
![enter image description here][411]
![enter image description here][412]
I also printed in metal powder processing with German equipment of [EOS M 290][413]. It's a 1 million dollars equipment with advanced additive manufacturing technology. The printed coins are made in material of stainless steel power. It has 40 mm outside diameter and 3 mm thickness, with thinnest region at coin plate only 0.5mm. It weights 15 grams. As you can see from the metal spikey coin, the relief pattern is clearly distinguishable. All faces of triangle form an optical diffuse reflection.
![enter image description here][414]
![enter image description here][415]
![enter image description here][416]
**4.4 Tips for 3D Printing**
- 3D printing model should be in good quality. Export STL from
Graphics3D is not good enough for 3D printing. Region is much better
and restrict define. You can kick Printing3D report and check your
model quality. Discretization and defects should all be checked and
passed.
![enter image description here][417]
- For a thin model, horizontal placement (background plane is put flat
on the printing table) results a poor resolution in sculpture.
Vertical or tilted placement wold helps to increase printable layers
and improve detail resolution in the relief.
5. Greetings
------------
This project was supported a lot friends. Thank you to all my friends in Wolfram China Community.
Finally, Yang and my family would like to share some images below for this moment as holiday greetings to all world-wide friends in Wolfram Community.
![enter image description here][51]
![enter image description here][52]
![enter image description here][53]
![enter image description here][54]
![enter image description here][55]
[51]: https://community.wolfram.com//c/portal/getImageAttachment?filename=G1.jpg&userId=569571
[52]: https://community.wolfram.com//c/portal/getImageAttachment?filename=G2.jpg&userId=569571
[53]: https://community.wolfram.com//c/portal/getImageAttachment?filename=G3.jpg&userId=569571
[54]: https://community.wolfram.com//c/portal/getImageAttachment?filename=G4.jpg&userId=569571
[55]: https://community.wolfram.com//c/portal/getImageAttachment?filename=G5.jpg&userId=569571
[41]: https://community.wolfram.com//c/portal/getImageAttachment?filename=408.png&userId=569571
[42]: https://community.wolfram.com//c/portal/getImageAttachment?filename=409.png&userId=569571
[43]: https://community.wolfram.com//c/portal/getImageAttachment?filename=410.gif&userId=569571
[44]: https://community.wolfram.com//c/portal/getImageAttachment?filename=412.png&userId=569571
[45]: https://community.wolfram.com//c/portal/getImageAttachment?filename=411.png&userId=569571
[46]: https://community.wolfram.com//c/portal/getImageAttachment?filename=423Processing_H1.gif&userId=569571
[47]: https://community.wolfram.com//c/portal/getImageAttachment?filename=422Processing_V1.gif&userId=569571
[48]: https://community.wolfram.com//c/portal/getImageAttachment?filename=421GIF_SLA.gif&userId=569571
[49]: https://community.wolfram.com//c/portal/getImageAttachment?filename=423SLA_SpikeyCoin.gif&userId=569571
[410]: https://community.wolfram.com//c/portal/getImageAttachment?filename=423.png&userId=569571
[411]: https://community.wolfram.com//c/portal/getImageAttachment?filename=431GIF_MetalPower.gif&userId=569571
[412]: https://community.wolfram.com//c/portal/getImageAttachment?filename=431.png&userId=569571
[413]: https://www.eos.info/eos-m290
[414]: https://community.wolfram.com//c/portal/getImageAttachment?filename=432.png&userId=569571
[415]: https://community.wolfram.com//c/portal/getImageAttachment?filename=433.png&userId=569571
[416]: https://community.wolfram.com//c/portal/getImageAttachment?filename=434SS_SpikeyCoin.gif&userId=569571
[417]: https://community.wolfram.com//c/portal/getImageAttachment?filename=441.png&userId=569571
[31]: https://community.wolfram.com//c/portal/getImageAttachment?filename=31.png&userId=569571
[32]: https://community.wolfram.com//c/portal/getImageAttachment?filename=32GIF.gif&userId=569571
[33]: https://community.wolfram.com//c/portal/getImageAttachment?filename=33.png&userId=569571
[34]: https://community.wolfram.com//c/portal/getImageAttachment?filename=34.png&userId=569571
[21]: https://community.wolfram.com//c/portal/getImageAttachment?filename=21.png&userId=569571
[22]: https://community.wolfram.com//c/portal/getImageAttachment?filename=22.png&userId=569571
[23]: https://community.wolfram.com//c/portal/getImageAttachment?filename=23.png&userId=569571
[24]: https://community.wolfram.com//c/portal/getImageAttachment?filename=24.png&userId=569571
[25]: https://community.wolfram.com//c/portal/getImageAttachment?filename=25.png&userId=569571
[26]: https://community.wolfram.com//c/portal/getImageAttachment?filename=26.png&userId=569571
[27]: https://community.wolfram.com//c/portal/getImageAttachment?filename=27.png&userId=569571
[28]: https://community.wolfram.com//c/portal/getImageAttachment?filename=28.png&userId=569571
[11]: https://en.wikipedia.org/wiki/Relief
[12]: https://community.wolfram.com//c/portal/getImageAttachment?filename=10.png&userId=569571
[13]: http://demonstrations.wolfram.com/DesignYourOwnCommemorativeCoin/
[14]: https://community.wolfram.com//c/portal/getImageAttachment?filename=11.png&userId=569571
[15]: https://community.wolfram.com//c/portal/getImageAttachment?filename=12.png&userId=569571
[16]: https://community.wolfram.com//c/portal/getImageAttachment?filename=13.png&userId=569571
[17]: https://community.wolfram.com//c/portal/getImageAttachment?filename=14.png&userId=569571
[1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=01.png&userId=569571
[2]: https://reference.wolfram.com/language/ref/BlockchainData.html
[3]: http://blog.wolfram.com/2018/06/21/weve-come-a-long-way-in-30-years-but-you-havent-seen-anything-yet/
[4]: https://community.wolfram.com//c/portal/getImageAttachment?filename=02.png&userId=569571
[5]: http://mathworld.wolfram.com/Spikey.html
[6]: https://www.wolfram.com/
[at0]: https://community.wolfram.com/web/wufei1978
[at1]: https://community.wolfram.com/web/shenghuiyFrederick Wu2018-12-12T10:46:24ZA Prime Pencil
https://community.wolfram.com/groups/-/m/t/1569707
![a very prime pencil][1]
I just got a set of these pencils, from [Mathsgear][2].
The number printed on it is prime, and will remain so as you sharpen the pencil from the left, all the way down to the last digit, 7.
Here is a recursive construction of all such *truncatable primes*.
TruncatablePrimes[p_Integer?PrimeQ] :=
With[{digits = IntegerDigits[p]},
{p, TruncatablePrimes /@ (FromDigits /@ (Prepend[digits, #] & /@ Range[9]))}
];
TruncatablePrimes[p_Integer] := {}
The one on the pencil is the largest one,
In[7]:= Take[Sort[Flatten[TruncatablePrimes /@ Range[9]]], -5]
Out[7]= {
9918918997653319693967,
57686312646216567629137,
95918918997653319693967,
96686312646216567629137,
357686312646216567629137}
[1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=IMG_20181212_120939.jpg&userId=143131
[2]: https://mathsgear.co.uk/products/truncatable-prime-pencilRoman Maeder2018-12-12T12:01:36Z[MAKE] Boot Logo for a Laptop
https://community.wolfram.com/groups/-/m/t/1570390
**[Open in Cloud][1] | Attachments for Desktop at the End**
*_WARNING: Customizing boot logo of the laptop might require flash the BIOS firmware, which has a small chance to fail and permanently "brick" the laptop!_*
![enter image description here][2]
Just as many people, I do a lot of work on my laptop. And naturally, just like many people, I want to customize it to feel like "mine". One thing I always wanted was to change the boot logo, since that's the first thing you see when you wake up your electric friend. Image my excitement when I found out that there's an official BIOS Update Utility just for that for my ThinkPad T440s! The only catch, according to the vaguely written documentation in the utility, and a bunch of internet articles I found, it seems that the logo designs are subject to certain constraints:
1. the most suitable format is **GIF**
2. image dimensions must be **less than 768 x 432**
3. image must be below **30KiB**.
Having got that out of the way, it's time to make my awesome logo!
As a start, I generated a vector drawing using the _Constantia_ font and the lovely `\[LightBulb]` icon.
vectorgraph = ExportString[
Style["i\[LightBulb]ea", 100, Bold, FontFamily -> "Constantia"] // Echo
, "PDF"] //
ImportString[#, "PDF"][[1]] &
![vectorgraph][3]
I wanted my logo to look low-poly styled. Firstly, I made the edges jagged by chossing a large value for `MaxCellMeasure`.
bregionInit = vectorgraph // BoundaryDiscretizeGraphics[ #, MaxCellMeasure -> 10 ] &
![bregionInit][4]
Next, I trianglized the region with `TriangulateMesh`. For the same reason, a large `MaxCellMeasure` really helps to give the low-poly effect. In addition, a high `MeshQualityGoal` is necessary to create somewhat regular triangle pieces.
At this point, the **30KiB** limitation I talked about earlier comes into play. Many triangles means more details means larger file size, even for GIF. Through some good old eye-balling, I settled on a value of 0.7, which manages to look great while still staying under the limit.
mesh = TriangulateMesh[ bregionInit
, MeshQualityGoal -> .7
, MaxCellMeasure -> 200 ]
![mesh][5]
The shape looks good to me. For afterward manipulation, let's collect all the triangles with their positions.
polys = MeshPrimitives[mesh, 2];
centers = PropertyValue[{mesh, 2}, MeshCellCentroid];
polys // Short
centers // Short
(*
{Polygon[{{2.115,19.2363},{4.8094,19.2363},{1.94625,20.9013}}],<<367>>,Polygon[<<1>>]}
{{2.95688,19.7913},<<367>>,{58.7516,38.3716}}
*)
Pretty good, but better with some colors!
One possible way to paint my triangles is to shade them according to their heights.
To do that I extracted the heights and rescaled them to get a percentage $\lambda$ so those near the central horizontal line have values near 0, and those furthest have values near 1. It will serve as a "gradient mask" for later use.
λs = centers[[;; , 2]] // RightComposition[
Through@*{Identity, Mean}
, Apply[Subtract]
, Abs /* Rescale
];
Time to choose a color scheme. I find `"StarryNightColors"` very delightful.
polysNew = MapThread[Function[{p, c, λ},
{
FaceForm[ColorData["StarryNightColors"][2 λ]]
, p}
]
, {polys, centers, λs}
, 1];
polysNew // Shallow /* Short
(*
{{FaceForm[<<1>>],Polygon[<<1>>]},{FaceForm[<<1>>],Polygon[<<1>>]},<<7>>,{FaceForm[<<1>>],Polygon[<<1>>]},<<359>>}
*)
logo = Graphics[{polysNew}, Background -> Black, PlotRangePadding -> 0]
![logo_1][6]
Looks much better now, isn't it?
However, I am still not satisfied. Bearing in mind the file size restriction, maybe I can experiment with some geometric transformations?
logo = Block[{
polysNew,
λTransFunc = Function[x, (1 - Cos[π/2 x]^3)/2]
},
polysNew = MapThread[Function[{p, c, λ},
{
FaceForm[ColorData["StarryNightColors"][2 λ]]
, MapAt[(1 - λ) # + λ c &, {1, ;;}]@p}
]
, {polys, centers, λs // λTransFunc}
, 1];
Graphics[{polysNew}, Background -> Black, PlotRangePadding -> 0]
]
![logo_2][7]
Not bad, except that the central pieces are now waaay too dark. Let's add some bright edges for them.
logo = Block[{
polysNew,
λTransFunc = Function[x, (1 - Cos[π/2 x]^3)/2]
},
polysNew = MapThread[Function[{p, c, λ},
{
If[λ > .3, {},
EdgeForm@{GrayLevel[1 - λ^.5], AbsoluteThickness[0]}
]
, FaceForm[ColorData["StarryNightColors"][2 λ]]
, MapAt[(1 - λ) # + λ c &, {1, ;;}]@p}
]
, {polys, centers, λs // λTransFunc}
, 1];
Graphics[{polysNew}, Background -> Black, PlotRangePadding -> 0]
]
![logo_3][8]
The warming yellow has been restricted to the light bulb, leaving me pure deep blue glossy letters. I think I'm good to go :D
To fit the constraint of the utility tool, the final work is to rasterize the image and export it to GIF.
logoImg = logo //
RightComposition[
Image[#, ImageSize -> 1000] &
, ImagePad[#, 50, Black] &
, ImageResize[#, 768 + 45] &
, ImageCrop
];
logoFile = Export[
FileNameJoin[{NotebookDirectory[], "logoImg.gif"}]
, logoImg
, "GIF"
];
Unfortunately, despite my very carefully tuning, the resulting GIF still exceeded the file size limitation of 30KiB.
FileSize[logoFile] // UnitConvert[#, "Kibibytes"] &
48.8789KiB
I searched around and came to a commandline tool called [Gifsicle](https://github.com/kohler/gifsicle). The following command (run in OS' console) finally did the trick. Hurray!
gifsicle -k 50 -O3 --no-extensions --no-comments < logoImg.gif > LOGO2.gif
Now check the perfect file size,
FileSize[FileNameJoin[{NotebookDirectory[], "LOGO2.gif"}]] //
UnitConvert[#, "Kibibytes"] &
29.7598KiB
The rest is refreshingly straight forward. I dropped my LOGO2.GIF in the utility's own directory and executed the firmware update utility. It automatically picked up the logo image and proceeded to modify my firmware. One reboot later, I was rewarded by my very own boot logo!
![t440s boot image][9]
_Easter eggs:_
Can you guess what happened when I remembered my another old ThinkPad the next day?
![other boot image][10]
(The color scheme used here was `"CoffeeTones"`.)
At last, the family photo of my electric friends :)
![family photo][11]
----
Thanks for watching and ... ...
*Stay tuned!* Next post we will share our experiment on making cool booting animation with *Mathematica* for Android phones! :)
[1]: https://www.wolframcloud.com/objects/wolfram-community/MAKE-Boot-Logo-for-a-Laptop-by-Silvia-Hao
[2]: https://community.wolfram.com//c/portal/getImageAttachment?filename=ScreenShot2018-12-14at4.35.36AM.jpg&userId=11733
[3]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_font.png&userId=93201
[4]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_bdRegion.png&userId=93201
[5]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_tRegion.png&userId=93201
[6]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_1.png&userId=93201
[7]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_2.png&userId=93201
[8]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_3.png&userId=93201
[9]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_t440s.png&userId=93201
[10]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_other.png&userId=93201
[11]: https://community.wolfram.com//c/portal/getImageAttachment?filename=logo_family.png&userId=93201Silvia Hao2018-12-13T17:51:14Z[GIF] Bounce ((3,1)+(1,3) vibration mode of a square membrane)
https://community.wolfram.com/groups/-/m/t/1567736
![(3,1)+(1,3) vibration mode of square membrane][1]
**Bounce**
The vibration modes of a rectangular membrane of width $L_x$ and length $L_y$ are
$\Psi_{mn}(x,y) = \sin\left(\frac{\pi m}{L_x}x\right) \sin\left(\frac{\pi n}{L_y}y\right);$
in other words, each direction just consists of standing waves with wavelength given by the reciprocal of some integer multiple of the length of the side of the membrane.
Ψ[m_, n_, {x_, y_}] := Sin[m π x] Sin[n π y];
In general these modes all have different frequencies, but when, e.g., one side length is a multiple of the other, it is possible for two different modes to have the same frequency, and then linear combinations of modes of the same frequency will also be vibration modes of the membrane. See [Dan Russell's demo][2] for more.
This animation shows the combination of the $(1,3)$ mode and the $(3,1)$ mode of the square where each factor is equally weighted. (Compare previous vibration mode animations [_Square Up_][3], [_Drumbeat_][4], and [_Things That Go Bump in the Night_][5]).
Here's the code:
DynamicModule[{n = 25, a = 1.2, dots,
cols = RGBColor /@ {"#0098d8", "#f54123", "#0b3536"}},
Manipulate[
dots = Table[
{2 π (x - 1)/n, 2 π (y - 1)/n,
Cos[θ] (1/Sqrt[2] Ψ[3, 1, {(x - 1)/n, (y - 1)/n}] + 1/Sqrt[2] Ψ[1, 3, {(x - 1)/n, (y - 1)/n}])},
{x, 1, n + 1}, {y, 1, n + 1}];
Graphics3D[
{AbsoluteThickness[2],
Table[
Line[#[[i]], VertexColors -> (Blend[cols[[;; -2]], (# + a)/(2 a)] & /@ #[[i, ;; , 3]])],
{i, Length[#]}] & /@ {dots, Transpose[dots]}},
Boxed -> False, PlotRange -> {{0, 2 π}, {0, 2 π}, {-2, 2}},
ImageSize -> 540, ViewPoint -> {2, 0, 1/2},
SphericalRegion -> True, Background -> cols[[-1]]],
{θ, 0, 2 π}]
]
[1]: https://community.wolfram.com//c/portal/getImageAttachment?filename=rolling34Lr.gif&userId=610054
[2]: https://www.acs.psu.edu/drussell/Demos/rect-membrane/rect-mem.html
[3]: https://community.wolfram.com/groups/-/m/t/896369
[4]: https://community.wolfram.com/groups/-/m/t/899038
[5]: https://community.wolfram.com/groups/-/m/t/985795Clayton Shonkwiler2018-12-07T21:38:05ZThe "Mathy" Arts of Coding Postcards
https://community.wolfram.com/groups/-/m/t/1569557
**[Open in Cloud][1]** | **Attachments for Desktop at the End** | *LARGE images, wait till they load*
----------
![enter image description here][2]
----------
And so, the holidays are upon us once more and celebrations are in order. Wolfram Language fans enjoy fun recreation and arts, because beautiful things can be made with beautiful code, concise and elegant. I wanted to find a few gems from the past to honor the holidays and the traditions our users have. Surprisingly those few gems combined into one Christmas postcard you can see above.
The story of this postcard begins six years ago, when our sister community Mathematica Stack Exchange sprang up a question about simulating a snow fall with Wolfram Language. One of Wolfram most creative users, [@Simon Woods][at0] gave a [wonderful answer][3] that was very popular. Then about five years ago I have run into a [viral Reddit discussion][4] dubbed
$$t * sin (t) ≈ Christmas tree$$
which showcased a beautiful minimalistic Christmas tree built with simple $t * sin (t)$ function and Java Script. I recreated the concept with Wolfram Language and our another wonderful user [@Silvia Hao][at1] ornamented it with [festoon lamps][5]. An idea came to me to combine them, because a Christmas Tree sparkling lights in a snowfall is the icon of winter holidays. But beware a few subtle tricks ;-) In depth those discussed at the original references I gave. Below are slightly changed code and a few comments.
## The Tree
Our Christmas Tree is indeed spun with $t * sin (t)$. But in 3D rather than 2D. This is basically a conical spiral whose amplitude increases, a 2D circle dragged along 3-rd axis like [this][6]:
![enter image description here][7]
but only with increasing radius. Density of lights and their motion is one subtlety to take care of with math. Another subtlety is increasing 3D depth perception by slightly dimming the lights that are further from the observer. This function defines the mathematics of the tree:
PD = .5;
s[t_, f_] := t^.6 - f
dt[cl_, ps_, sg_, hf_, dp_, f_, flag_] :=
Module[{sv, basePt},
{PointSize[ps],
sv = s[t, f];
Hue[cl (1 + Sin[.02 t])/2, 1, .8 + sg .2 Sin[hf sv]],
basePt = {-sg s[t, f] Sin[sv], -sg s[t, f] Cos[sv], dp + sv};
Point[basePt],
If[flag,
{Hue[cl (1 + Sin[.1 t])/2, 1, .8 + sg .2 Sin[hf sv]], PointSize[RandomReal[.01]],
Point[basePt + 1/2 RotationTransform[20 sv, {-Cos[sv], Sin[sv], 0}][{Sin[sv], Cos[sv], 0}]]},
{}]
}]
and this code uses the function to build 228 frames of the animated tree:
treeFrames = ParallelTable[
Graphics3D[Table[{
dt[1, .01, -1, 1, 0, f, True],
dt[.45, .01, 1, 1, 0, f, True],
dt[1, .005, -1, 4, .2, f, False],
dt[.45, .005, 1, 4, .2, f, False]},
{t, 0, 200, PD}],
ViewPoint -> Left, BoxRatios -> {1, 1, 1.3},
ViewVertical -> {0, 0, -1}, Boxed -> False,
ViewCenter -> {{0.5, 0.5, 0.5}, {0.5, 0.55}},
PlotRange -> {{-20, 20}, {-20, 20}, {0, 20}},
Background -> Black,ImageSize->350],
{f, 0, 1, .0044}];
Let's check a single frame of THe Tree:
First[treeFrames]
![enter image description here][8]
## The Snow
This function below builds a single random snowflake. They are of course six-fold symmetric polygons.
flake := Module[{arm},
arm = Accumulate[{{0, 0.1}}~Join~RandomReal[{-1, 1}, {5, 2}]];
arm = arm.Transpose@RotationMatrix[{arm[[-1]], {0, 1}}];
arm = arm~Join~Rest@Reverse[arm.{{-1, 0}, {0, 1}}];
Polygon[Flatten[arm.RotationMatrix[# \[Pi]/3] & /@ Range[6], 1]]];
Let's see a few random shapes, they are fun in black on white ;-)
Multicolumn[Table[Graphics[flake, ImageSize -> 50], 100], 10]
![enter image description here][9]
Now it's time to build the `snowfield` which has a few tricks. To simulate 3D perception 2 things need to be obsereved:
1. Real further snowflakes appear smaller
2. Real further snowflakes have slower perceived angular speeds
The 2nd observation is taken care of by the `size_` variable below.
snowfield[flakesize_, size_, num_] :=
Module[{x = 100/flakesize},
ImageData@
Image[Graphics[{White,Opacity[.8],
Table[Translate[
Rotate[flake, RandomReal[{0, \[Pi]/6}]], {RandomReal[{0, x}],
RandomReal[{0, x}]}], {num}]}, Background -> Black,
PlotRange -> {{0, x}, {0, x}}], ImageSize -> {size, size}]];
and by 3 different sizes given here:
size=455;
r=snowfield@@@{{.9,size,250},{1.2,size,30},{1.6,size,10}};
So we sort of have 3 different fields of vision reproaching the observer. The 1st observation is simulated with different speed with which different fields of vision are rotated, the closer one being the fastest. This simulates rotation of the fields of vision and builds the frames for the snowfall:
snowFrames=ParallelTable[Image[Total[(RotateRight[r[[#]],k #]&/@{1,2,3})[[All, ;;size]]]],{k,0,455,2}];
## The Postcard
Slight opacity is needed to to blend The Tree and The Snow appealingly. The opacity is given the snowflakes in the code above and `SetAlphaChannel` below is formally needed for image data to have the same dimensions (3 RGB + 1 Opacity channels) and to be able to combine. This builds the final frames
finalFrames=
Parallelize[MapThread[
ImageAdd[SetAlphaChannel[#1,1],#2]&,
{treeFrames,snowFrames}]];
and this exports the frames to the GIF you see at the top of the post:
Export["xmas.gif", finalFrames,"AnimationRepetitions"->Infinity]
I hope you had fun. Feel free to share your own crafts. Happy holidays!
[at0]: https://community.wolfram.com/web/swoods1
[at1]: https://community.wolfram.com/web/wyelen
[1]: https://www.wolframcloud.com/objects/wolfram-community/The-Mathy-Arts-of-Coding-Postcards-by-Vitaliy-Kaurov
[2]: https://community.wolfram.com//c/portal/getImageAttachment?filename=8701ezgif.com-optimize.gif&userId=11733
[3]: https://mathematica.stackexchange.com/a/16889/13
[4]: https://redd.it/1tswai
[5]: https://community.wolfram.com/groups/-/m/t/175891
[6]: https://en.wikipedia.org/wiki/File:ComplexSinInATimeAxe.gif
[7]: https://community.wolfram.com//c/portal/getImageAttachment?filename=ComplexSinInATimeAxe.gif&userId=11733
[8]: https://community.wolfram.com//c/portal/getImageAttachment?filename=534yrsgfdgbd.png&userId=11733
[9]: https://community.wolfram.com//c/portal/getImageAttachment?filename=435wyrhgsfdasaW.png&userId=11733Vitaliy Kaurov2018-12-12T00:56:35Z