Group Abstract Group Abstract

Message Boards Message Boards

[GIF] Infinitely happy holidays w/ shaped text

Posted 10 years ago

enter image description here

There are probably many approaches to geometric shaping of a text. Can you suggest an idea or a reference? Because text can be easily transformed into a graphical or geometric object in WL, we could use functions such as TransformedRegion, GeometricTransformation, ImageEffect, etc. We can also imagine creating a region and somehow confining the text to it. But text is intended to be readable (mostly), so its linearity should be preserved more or less. This leads to the known simple idea:

  1. Direct text along a curve
  2. Modulate text size locally as you go along the curve

A few nice solutions to the 1st part are given in the discussion Movable text on a curve. I will closely recreate one approach (by Michael E2) a bit updating it and introducing the 2nd part of modulation. We will build the animation you can see above at the top of this post. We start from transforming some text into a graphical object:

txtbase = ImportString[ExportString[
"infinitely happy holidays to you and yours and may all your wishes come true", "PDF"], "PDF"];
txt = First@First@txtbase;

Next is defining some range which is raw length of our text scaled by some factor to fit nicely on a given curve:

xRange = -Subtract @@ First[PlotRange /. First@AbsoluteOptions[txtbase, PlotRange]]/2.4 

And here is the curve which I shape as Infinity:

c[t_] := {2 Cos[2 ? t], Sin[4 ? t]};
ParametricPlot[c[t], {t, 0, 1}]

We need its total arclength which can be found old school or a new V10 way:

totalarclength = NIntegrate[Sqrt[c'[t].c'[t]], {t, 0, 1}]
(*12.194446940169746`*)
totalarclength = ArcLength[N@c[t], {t, 0, 1}]
(*12.194446940169746`*)

Let's find how parametric variable $t$ depends on arclength $s$ and define a normal:

invarclength = 
  NDSolveValue[{D[t[s], s] Sqrt[c'[t[s]].c'[t[s]]] == 1, t[0] == 0}, t, {s, 0, totalarclength}];

NN[t_] := {{0, -1}, {1, 0}}.c'[t]/Sqrt[c'[t].c'[t]];

This is the function that will transform text:

maptext[s_, \[CapitalDelta]n_] := 
  With[{t = invarclength[Mod[s, totalarclength]]}, c[t] + \[CapitalDelta]n NN[t]]; 

This lets you play with parameters and modulation that we defined as a simple $Sin$ function:

Manipulate[Show[
  ParametricPlot[c[t], {t, 0, 1}, PlotStyle -> Directive[Red, Opacity[.2], Dashed]],
  Graphics[Dynamic@{txt /. {x_Real, y_Real} :> maptext[-fs x/xRange - s0, 
  -fs (1 + .5 Sin[20 x/xRange - s0]) y/ xRange + \[CapitalDelta]N]}],
  PlotRange -> {{-2.1, 2.1}, {-1.1, 1.1}}, Axes -> False,  ImageSize -> 800],
 {{\[CapitalDelta]N, .15}, -1, 1}, {{s0, 0}, 0, totalarclength}, {{fs, 5, "font scale"}, 0.1, 5}]

enter image description here

In the attached notebook you can find a bit more code to make effects like shadows and produce the animation above. Share your thoughts on how you would shape text! I also encourage you to improve this or/and package your function as something like ShapedText[...] so we can share it more easily. This method here needs some integrity to include, for example, splines and depend on more clear parameters - especially for modulation. Happy holidays!

enter image description here

Attachments:
POSTED BY: Vitaliy Kaurov
5 Replies
POSTED BY: Michael Rogers

This is very skillful and instructive, @Michael Rogers, thank you for taking the time and sharing this !

POSTED BY: Vitaliy Kaurov
POSTED BY: Michael Rogers
POSTED BY: Vitaliy Kaurov
POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard