From Newsgroup: comp.lang.postscript
The PostScript command `arc` can draw circles, and part circles. Adobe Distiller draws angles ren90-# as a single B|-zier cubic.
A B|-zier cubic has eight parameters, `curveto` receiving the two from the `currentpoint`, and six from the stack. An arc must go through the correct endpoints, using four parameters. At the endpoints the direction of travel must be tangent to the circle, so each end absorbs another parameter. And, by symmetry, at the two ends the speeds of departure must be the same. rf|N+A-aOnly one parameter remains to be chosen, being the speed of departure from the endpoints.
For a 90-# part of a unit circle, Adobe uses a speed of 0.552. Mathematica shows that the worst error happens at t ree 0.18864 (and at one minus this), an angle ree-a17.39-# (and 90-# minus this) where the radius is too large by about 212 parts per million. At t-a=-a-+, angle-a=-a45-#, the radius is too small by reA151 parts per million. These values are confirmed by testing with `flattenpath` rCa `pathforall`.
For a circle of radius 540pt-a=-a7-+rC| =-a190.5mm, plausible on A4 or 8-+rC||u11rC|, the error is as large as 0.1145pt.
Typically, a ree0.04mm error doesnrCOt matter: the eye would not perceive it midst an empty page. But if a circle is being drawn with `arc`, and things placed at its edge (locations computed with `sin` and `cos`), as my software
http://github.com/jdaw1/placemat/ does, then these things could be falsely apart by 0.11pt. That isnrCOt a disaster, but could be a multi-pixel visible imperfection. And an unnecessary imperfection.
This is solved by new PostScript routines `ArcPrecise`, and |a la `arcn`, `ArcPreciseN`.
http://www.jdawiseman.com/2022/ArcPrecise.ps http://www.jdawiseman.com/2022/ArcPrecise.pdf http://www.jdawiseman.com/2022/ArcPrecise_bitmap_17.png (Adobe error of +212-appm)
http://www.jdawiseman.com/2022/ArcPrecise_bitmap_73.png (Adobe error of +212-appm)
http://www.jdawiseman.com/2022/ArcPrecise_bitmap_45.png (Adobe error of reA151-appm)
http://www.jdawiseman.com/2022/ArcPrecise_bitmap_06.png (worst ArcPrecise error, +0.37-appm)
Output is shown in the PDF and the .png extracts from it. The grey line, width 0.36pt, is a precise circle, made of tiny `lineto`s only rac-# apart. Underneath is a red line, width 0.60pt, drawn with AdoberCOs `arc`, the red diagonals touching its worst radii. On top is a blue line, width 0.12pt, drawn with `ArcPrecise`, short blue lines touching its worst points. The widths are chosen such that, where all are neatly aligned, each stripe of colour has width 0.12pt. Throughout, the grey and the blue are neatly aligned; but the red drifts out by almost 0.12pt, then in, then back out.
Assume curve of angle ++. A speed of Tan[++/4]-+4/3 has the radius precisely correct at the midpoint, t-a=-a-+, angle-a=-a++/2. The radius is never too small, and is maximal at t-a=-a-+-areA-araOreU3 ree-a0.2113. For ++ small and in radians, the maximal radius happens near angle (-+-areA-araOreU3)-+++ ree-a0.2113-a++, where the radius is too big by ree-a2rU+-|-|-+3rU+-|-+++rU| =-a(++^6)/55296.
`ArcPrecise` chooses curves of no more than 30-#. For a 30-# curve the actual worst error is 0.372662 parts per million; this approximation says -CrU|/2579890176-areA-a1 ree-a0.372647-appm. So it is a good approximation to the error.
For a 540pt radius, `ArcPrecise` has a peak error of 0.00020pt. If the smallest error we care about is 0.01pt, half a pixel at 3600d.p.i., that doesnrCOt happen with radius-aren-a9.46-ametres ree-a31-afeet. This is bigger than the PDF standardrCOs maximum page size of only 200rC|-a=-a16rao-afeet =-a5.08-ametres. Further, PostScriptrCOs arithmetic is single-precision, with a 23-bit mantissa, which is only slightly more accurate than 0.37-appm. So 30-# curves are sufficiently small.
There is also a little neatness in the choice of curve-end angles. If every multiple of 90-# is a curve endpoint, then `pathbbox` returns the correct minimal box. So the angle choosing algorithm works as follows. It computes the next multiple of 90-#, If thatrCOs ren30-# away, done in one curve; else if ren60-# away, done in two equal-angle curves; otherwise split into three equal-angle curves. Then 30-# curves until the final multiple of 90-#; the final section, like the first, in at most three equal-angle curves each ren30-#. This means that: curves are all ren30-#; for a non-rotated frame `pathbbox` works optimally; and the number of curves is at most 1-a+-arie|angree-areA-aangreU|-a|+-a30-#rie.
The build-in routines start with a line from a currentpoint, if there is one. This is annoying. Consider an annulus: thererCOs a line between the inner and outer circles, avoiding which requires a manual moveto. `ArcPrecise` and `ArcPreciseN` prevent this annoyance by starting, always, with a moveto, never a lineto.
Comment welcomed.
--- Synchronet 3.21d-Linux NewsLink 1.2