13

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]
matrix42
  • 6,996
  • 2
  • 26
  • 62
  • 1
    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. – Nasser Sep 29 '21 at 08:19
  • Related to this old question of mine (with two answers). – rhermans Sep 29 '21 at 09:05
  • 5
    @Nasser - if the disk is shaking I don't see it. The text is definitely shaking relative to the disk though – Jason B. Sep 29 '21 at 11:14
  • 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. – anjama Sep 29 '21 at 23:16

4 Answers4

7

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]

Jason B.
  • 68,381
  • 3
  • 139
  • 286
4

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]

Nasser
  • 143,286
  • 11
  • 154
  • 359
4

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

Carl Lange
  • 13,065
  • 1
  • 36
  • 70
2

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]
Syed
  • 52,495
  • 4
  • 30
  • 85