13
$\begingroup$

I'm making a simple animation, found that the text is always slight shake. I think this is not a precision problem. Maybe related to rendering? Is there a related option or this workaround?
enter image description here

Animate[Graphics[{Circle[],{Disk[{Cos@t,Sin@t},0.18],
 Text[Style["P",White,36,Italic,FontFamily->"Times"],{Cos@t,Sin@t}]}},PlotRange->1.5]
,{t,0,2Pi},AnimationRate->.01]
$\endgroup$
4
  • 1
    $\begingroup$ It is the disk that appears to shake. Try Animate[Graphics[{Circle[], {Disk[{Cos@t, Sin@t}, 0.18]}}, PlotRange -> 1.5], {t, 0, 2 Pi}, AnimationRate -> .01] and you'll see the disk that that shakes with no text. If you change the animation rate to say AnimationRate -> .005 you'll see this more clearly. $\endgroup$
    – Nasser
    Sep 29 at 8:19
  • $\begingroup$ Related to this old question of mine (with two answers). $\endgroup$
    – rhermans
    Sep 29 at 9:05
  • 5
    $\begingroup$ @Nasser - if the disk is shaking I don't see it. The text is definitely shaking relative to the disk though $\endgroup$
    – Jason B.
    Sep 29 at 11:14
  • $\begingroup$ I don't have mathematica, so I can't provide a solution, but neither are actually jittering on their own. The position of "P" is being rounded to a whole pixel for rendering, whereas the circle is not. I presume it's just different rendering approaches for different types of objects (font rendering is surprisingly hard, btw). To see it, take the gif and throw into an online gif viewer that gives you reduce the playback speed, and then zoom way in. $\endgroup$
    – anjama
    Sep 29 at 23:16
6
$\begingroup$

I also find the inability to place text exactly within a graphic to be unacceptable, especially because many of the Graphics objects I produce have text within a disk, exactly like in the OP.

So I do something I consider a bit extreme - I convert every letter of the text into a FilledCurve object. How? By using this bit of code that was given to me by someone else (a bit of manna from heaven). I don't really understand the bit after FrontEndExecute, but I know it returns a Graphics. Then I take the filled curves inside that graphics and translate them to the origin, and use a GeometricTransformation to place it in the right spot.

toFilledCurves[input_] := 
  Module[{res, center}, 
   res = 
    ToExpression@
     First@
      FrontEndExecute@
       FrontEnd`ExportPacket[
        Cell[BoxData@ToBoxes[input], "Output", "Graphics", 
         "GraphicsLabel"], "InputForm", "Outlines" -> True];
   res = Cases[res, _FilledCurve, Infinity];
   center = 
    Mean[Flatten[Cases[res, FilledCurve[_, b_] :> b, Infinity], 2]];
   res /. 
    FilledCurve[x_, pts_] :> 
     FilledCurve[x, TranslationTransform[-center] /@ pts]
   ];

So this should produce an animation without jitters:

pCurve[center_, scale_] := 
  With[{p = 
     toFilledCurves[
      Style["P", White, 36, Italic, FontFamily -> "Times"]]},
   GeometricTransformation[p, 
    TranslationTransform[center]@*ScalingTransform[{scale, scale}]]];

Animate[Graphics[{Circle[], {Disk[{Cos@t, Sin@t}, 0.18], White, 
    pCurve[{Cos@t, Sin@t}, .008]}}, PlotRange -> 1.5], {t, 0, 2 Pi}, 
 AnimationRate -> .01]
$\endgroup$
2
  • $\begingroup$ What is fc? I cannot run this. I am on 12.2Win. $\endgroup$
    – Syed
    Sep 29 at 17:35
  • $\begingroup$ Sorry about that, should be fixed now $\endgroup$
    – Jason B.
    Sep 29 at 17:59
4
$\begingroup$

Here is an attempt. The idea is to render the disk once and rasterize it. Then use Inset to place it. You can play with the code to improve it more if needed. But now there is no shaking.

enter image description here

disk = Rasterize@
   Graphics[Disk[{0, 0}, 0.018], ImageSize -> 60];

Animate[
 Graphics[{Circle[], {Inset[disk, {Cos@t, Sin@t}], 
    Text[Style["P", White, 36, Italic, FontFamily -> "Times"], 
    {Cos@t,Sin@t}]}}, PlotRange -> 1.5],
 {t, 0, 2 Pi}, AnimationRate -> .01]
$\endgroup$
3
$\begingroup$

Another way to achieve the desired result is to use an ImageMesh of the rasterized text:

p = ImageMesh[
  Rasterize[
   Text[Style["P", White, 36, Italic, FontFamily -> "Times"]], 
   Background -> Black], MeshCellStyle -> {{2} -> White}, 
  Background -> Black, ImageSize -> 20]

Animate[Graphics[{Circle[], {Disk[{Cos@t, Sin@t}, 0.18], 
    Inset[p, {Cos@t, Sin@t}]}}, PlotRange -> 1.5], {t, 0, 2 Pi}, 
 AnimationRate -> .01]

enter image description here

$\endgroup$
2
$\begingroup$

If the "P" is rotated as well, it wobbles less. The wobble seems to be due to the x,y placement of the letter at every step. It seems to be climbing a staircase. To cancel the wobble exactly would require knowledge of the font design as well as that of other graphics primitives.

Animate[Graphics[{Circle[], {Disk[{Cos@t, Sin@t}, 0.18], 
    Text[Style[Rotate["P", t + 0.3], White, 36, Italic, 
      FontFamily -> "Times"], {Cos@t, Sin@t}]}}, 
  PlotRange -> 1.5], {t, 0, 2 Pi}, AnimationRate -> .01]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.