Skip to main content
replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
Source Link

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

Update

This can be improved by adding proper positioning by fixing the lower midpoint in the rotation and position. Also using Szabolcs very nice equidistant spacingsSzabolcs very nice equidistant spacings. However as I have stated in comments kerning is going to be trouble unless it's really taken seriusly into consideration.

 textOnCurve[text_,f_,n_,p_: 0.01]:=
 With[{angle=ArcTan@@Subtract@@(f/@Rescale[{n+p,n-p},{0,1},{p,1-p}])},
  Rotate[Text[text,f[n],{0,-1}],angle,f[n]]
 ]
 
equidistantTextCurve[string_,f_,stylef_: (#&),range_: {0,1}]:=
 Module[{chars,distance},
  chars=Characters@string;
  distance=functionEquidistant[f,Length@chars,range];
  MapIndexed[textOnCurve[stylef@#1,f,distance[[#2[[1]]]]]&,chars]
]

LocatorPane[Dynamic[pts],
Dynamic@(f = BezierFunction[pts];
 Show[Graphics[{Point[pts], Line[pts],
  equidistantTextCurve["Mathematica.StackExchange.Com", f, 
   Style[#, 18] &, {0.15, 0.8}]
  }, Frame -> True, PlotRange -> 2], 
 ParametricPlot[f[t], {t, 0, 1}]]), LocatorAutoCreate -> True]

Better curve text with equidistant characters

I'll leave it as an exercise to calculate proper kerning and getting an even better result.

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

Update

This can be improved by adding proper positioning by fixing the lower midpoint in the rotation and position. Also using Szabolcs very nice equidistant spacings. However as I have stated in comments kerning is going to be trouble unless it's really taken seriusly into consideration.

 textOnCurve[text_,f_,n_,p_: 0.01]:=
 With[{angle=ArcTan@@Subtract@@(f/@Rescale[{n+p,n-p},{0,1},{p,1-p}])},
  Rotate[Text[text,f[n],{0,-1}],angle,f[n]]
 ]
 
equidistantTextCurve[string_,f_,stylef_: (#&),range_: {0,1}]:=
 Module[{chars,distance},
  chars=Characters@string;
  distance=functionEquidistant[f,Length@chars,range];
  MapIndexed[textOnCurve[stylef@#1,f,distance[[#2[[1]]]]]&,chars]
]

LocatorPane[Dynamic[pts],
Dynamic@(f = BezierFunction[pts];
 Show[Graphics[{Point[pts], Line[pts],
  equidistantTextCurve["Mathematica.StackExchange.Com", f, 
   Style[#, 18] &, {0.15, 0.8}]
  }, Frame -> True, PlotRange -> 2], 
 ParametricPlot[f[t], {t, 0, 1}]]), LocatorAutoCreate -> True]

Better curve text with equidistant characters

I'll leave it as an exercise to calculate proper kerning and getting an even better result.

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

Update

This can be improved by adding proper positioning by fixing the lower midpoint in the rotation and position. Also using Szabolcs very nice equidistant spacings. However as I have stated in comments kerning is going to be trouble unless it's really taken seriusly into consideration.

 textOnCurve[text_,f_,n_,p_: 0.01]:=
 With[{angle=ArcTan@@Subtract@@(f/@Rescale[{n+p,n-p},{0,1},{p,1-p}])},
  Rotate[Text[text,f[n],{0,-1}],angle,f[n]]
 ]
 
equidistantTextCurve[string_,f_,stylef_: (#&),range_: {0,1}]:=
 Module[{chars,distance},
  chars=Characters@string;
  distance=functionEquidistant[f,Length@chars,range];
  MapIndexed[textOnCurve[stylef@#1,f,distance[[#2[[1]]]]]&,chars]
]

LocatorPane[Dynamic[pts],
Dynamic@(f = BezierFunction[pts];
 Show[Graphics[{Point[pts], Line[pts],
  equidistantTextCurve["Mathematica.StackExchange.Com", f, 
   Style[#, 18] &, {0.15, 0.8}]
  }, Frame -> True, PlotRange -> 2], 
 ParametricPlot[f[t], {t, 0, 1}]]), LocatorAutoCreate -> True]

Better curve text with equidistant characters

I'll leave it as an exercise to calculate proper kerning and getting an even better result.

Extended the answer with updated code and a new equidistant based method
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

Update

This can be improved by adding proper positioning by fixing the lower midpoint in the rotation and position. Also using Szabolcs very nice equidistant spacings. However as I have stated in comments kerning is going to be trouble unless it's really taken seriusly into consideration.

 textOnCurve[text_,f_,n_,p_: 0.01]:=
 With[{angle=ArcTan@@Subtract@@(f/@Rescale[{n+p,n-p},{0,1},{p,1-p}])},
  Rotate[Text[text,f[n],{0,-1}],angle,f[n]]
 ]
 
equidistantTextCurve[string_,f_,stylef_: (#&),range_: {0,1}]:=
 Module[{chars,distance},
  chars=Characters@string;
  distance=functionEquidistant[f,Length@chars,range];
  MapIndexed[textOnCurve[stylef@#1,f,distance[[#2[[1]]]]]&,chars]
]

LocatorPane[Dynamic[pts],
Dynamic@(f = BezierFunction[pts];
 Show[Graphics[{Point[pts], Line[pts],
  equidistantTextCurve["Mathematica.StackExchange.Com", f, 
   Style[#, 18] &, {0.15, 0.8}]
  }, Frame -> True, PlotRange -> 2], 
 ParametricPlot[f[t], {t, 0, 1}]]), LocatorAutoCreate -> True]

Better curve text with equidistant characters

I'll leave it as an exercise to calculate proper kerning and getting an even better result.

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

Update

This can be improved by adding proper positioning by fixing the lower midpoint in the rotation and position. Also using Szabolcs very nice equidistant spacings. However as I have stated in comments kerning is going to be trouble unless it's really taken seriusly into consideration.

 textOnCurve[text_,f_,n_,p_: 0.01]:=
 With[{angle=ArcTan@@Subtract@@(f/@Rescale[{n+p,n-p},{0,1},{p,1-p}])},
  Rotate[Text[text,f[n],{0,-1}],angle,f[n]]
 ]
 
equidistantTextCurve[string_,f_,stylef_: (#&),range_: {0,1}]:=
 Module[{chars,distance},
  chars=Characters@string;
  distance=functionEquidistant[f,Length@chars,range];
  MapIndexed[textOnCurve[stylef@#1,f,distance[[#2[[1]]]]]&,chars]
]

LocatorPane[Dynamic[pts],
Dynamic@(f = BezierFunction[pts];
 Show[Graphics[{Point[pts], Line[pts],
  equidistantTextCurve["Mathematica.StackExchange.Com", f, 
   Style[#, 18] &, {0.15, 0.8}]
  }, Frame -> True, PlotRange -> 2], 
 ParametricPlot[f[t], {t, 0, 1}]]), LocatorAutoCreate -> True]

Better curve text with equidistant characters

I'll leave it as an exercise to calculate proper kerning and getting an even better result.

added 46 characters in body
Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

This is just a quick sketching out of an answer (rescales galore!)

 textOnCurve[text_, f_, n_, p_: 0.01] := 
    Text[Rotate[text, ArcTan @@ (f[Rescale[n + p, {0, 1}, {p, 1 - p}]] - 
                                 f[Rescale[n - p, {0, 1}, {p, 1 - p}]])], f[n]]

 textCurve[string_, f_, stylef_: (# &), range_: {0, 1}] := 
  With[{chars = Characters@string}, 
  MapIndexed[textOnCurve[stylef@#1, f, Rescale[#2[[1]],{1, Length@chars}, range]] &, chars]]

Which can then be used like:

pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
LocatorPane[Dynamic[pts],
 Dynamic@(
  f = BezierFunction[pts];
  Show[Graphics[{Point[pts], Line[pts],
     textCurve["Some text here", f, Style[#, 20] &, {0.2, 0.6}]
     }, Axes -> True]
   , ParametricPlot[f[t], {t, 0, 1}]])
, LocatorAutoCreate -> True]

Curvy Text

Source Link
jVincent
  • 14.8k
  • 1
  • 44
  • 76
Loading