Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.postscript > #1748

Re: How does 'arc' work?

Newsgroups comp.lang.postscript
Date 2013-12-11 00:17 -0800
References <356283f9-d422-4515-8bd6-5ad0cf625f07@googlegroups.com> <a8c2ee20-a057-4055-8e35-cda59526aec7@googlegroups.com> <2bebfa0f-c416-44c3-aca4-2b0afbead55e@googlegroups.com> <dd7907b8-824f-4cfa-b797-08a99d902404@googlegroups.com> <55a3bc70-ad65-4552-9c33-c5cbd27c8c37@googlegroups.com>
Message-ID <77838e40-eac4-46cb-8372-4e642ad0f387@googlegroups.com> (permalink)
Subject Re: How does 'arc' work?
From luser- -droog <mijoryx@yahoo.com>

Show all headers | View raw


On Wednesday, December 11, 2013 1:02:08 AM UTC-6, luser- -droog wrote:
> On Sunday, December 1, 2013 5:58:18 AM UTC-6, luser- -droog wrote:
> 
> > On Sunday, December 1, 2013 5:48:50 AM UTC-6, luser- -droog wrote:
> 
> > 
> > > On Saturday, November 23, 2013 5:06:27 PM UTC-6, jdaw1 wrote:
> > > > For a quarter circle of unit radius, PostScript has the internal control points at (0,0.552) and (0.552,0). The number is likely to be an approximation to (√957 - 21)÷18 ≈ 0.55196759, which minimises ∫(r²–1)² wrt angle for a 90° cubic Bézier.
> 
> > > > 
> > > > 0.552 has the radius too large by a factor of 1 +0.000212 at 17.39° and 90–this, and too small by a factor of 1 –0.000151 at 45°. So the radius is correct to one part in at least ≈4714. At 1200 d.p.i., that’s correct to within a pixel for a diameters ≤ 7.857″ ≈ 19.96 cm.
> 
> > > 
> > > Ok. Thank you. That's very useful. I suppose for the remaining 
> > > segments I can find the points by an application of deCasteljau, 
> > > splitting until the desired angle and then discarding half of the 
> > > list. Might not be terribly efficient. But this is pass 1: 
> > > make it work.
> > 
> > 
> > 
> > I have found quite a few pdfs online that go into excruciating 
> > detail. But I haven't read them enough times to really 
> > understand it all yet. :)
> > 
> 
> Haven't quite solved it yet, but I've got some partial results worth 
> sharing, I think. Here are the resources I've found.
> 
> A gentle introduction to what's going on:
> http://whizkidtech.redprince.net/bezier/circle/
> 
> Don Lancaster's cubic spline page:
> http://www.tinaja.com/cubic01.shtml
> Particularly: http://www.tinaja.com/glib/bezarc1.pdf

Yes! This is the one. Last page, the second to last equations.
x1 = (4 - cos(a)) / 3
y1 = ((1 - cos(a))(cos(a) - 3)) / (3*sin(a))

> 
> Arcs to Beziers and vice versa:
> http://itc.ktu.lt/itc354/Riskus354.pdf
> 
> http://hansmuller-flex.blogspot.fr/2011/04/approximating-circular-arc-with-cubic.html
> 
> Implementation in processing:
> http://www.flong.com/blog/2009/bezier-approximation-of-a-circular-arc-in-processing/
> 
> So, what I've learned so far is, given as input the center point 
> (x,y), the radius r, and starting and ending angles a1 a2; the end-
> points are pretty easy P1 = (x+r*cos(a1),y+r*sin(a1)), P4 = 
> (x+r*cos(a2),y+r*sin(a2)). But the control points are trickier.
> 
> You can get the correct direction easily enough by taking the first
> derivative of the function, but the magnitudes are trickier.
> 
> I tried skimming through the above resources and using the magic 
> constant often mentioned, but it's only good for 90 degrees.
> 
> So I read further and discovered the way to get the control points
> was to select them such that the center point of the curve lies
> on the circle. Easier said than done.
> 
> I tried using the deCasteljau subdivision algorithm (backwards), 
> but after pages and pages of algebra, I could only get symmetrical 
> equations of the two control points, so upon substituting all the 
> crucial pieces disappear.
> 
> So I think the trick is to translate to the center, scale by the 
> radius, and rotate so the center of the angles is on the x axis.
> 
> Then x2 == x3 and y2 == -y3. And that simplifies everything.
> 
> I've still got some math to do, but this crucial insight (already
> mentioned in the Riskus paper), appears to be quite crucial.

So, repeating the revelation above:

 x1 = (4 - cos(a)) / 3
 y1 = ((1 - cos(a))(cos(a) - 3)) / (3*sin(a))

and of course

x2 = x1
y2 = -y1
x0 = cos(a)
y0 = cos(a)
x3 = x0
y3 = -y0

Woohoo!

So here's a portable postscript implementation for angles
from 0 to 90.

/arcbez { % draw single bezier % x y r angle1 angle2
    5 dict begin
    /mat matrix currentmatrix def 
    5 3 roll translate % r angle1 angle2
    3 2 roll dup scale % angle1 angle2
    2 copy exch sub /da exch def % da=a2-a1
    add 2 div rotate
    /da_2 da 2 div def 
    /sin_a da_2 sin def 
    /cos_a da_2 cos def 
    4 cos_a sub 3 div % x1
    1 cos_a sub cos_a 3 sub mul 
    3 sin_a mul div   % x1 y1
    neg 
    1 index           % x1 y1 x2(==x1)
    1 index neg       % x1 y1 x2 y2(==-y1)
    cos_a sin_a neg   % x1 y1 x2 y2 x3 y3
    cos_a sin_a       %               ... x0 y0
    4 { 8 2 roll transform } repeat
    mat setmatrix
    4 { 8 2 roll itransform } repeat
    { currentpoint pop pop } stopped { moveto }{ lineto } ifelse
    curveto
    end 
} def 

And for full circles:

% x y r angle1 angle2  arc  -
% append a circular arc to the current path
/arc {
    2 { dup 360 gt { dup 360 div truncate 360 mul sub } if exch } repeat
    2 { dup 0 lt { 360 add } if exch } repeat
    2 copy exch sub dup 90 gt { % recurse
        .5 mul % x y r a1 a2 da/2
        6 copy sub arc 
        3 2 roll add exch arc 
    }{ pop 
        % draw single bezier
        arcbez
    } ifelse
} def

Back to comp.lang.postscript | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-11-20 23:23 -0800
  Re: How does 'arc' work? bugbear <bugbear@trim_papermule.co.uk_trim> - 2013-11-21 14:05 +0000
    Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-12-01 04:03 -0800
  Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2013-11-23 15:06 -0800
    Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-12-01 03:48 -0800
      Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-12-01 03:58 -0800
        Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-12-10 23:02 -0800
          Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-12-11 00:17 -0800
            Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-12-11 00:20 -0800
              Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2013-12-11 01:37 -0800
              Re: How does 'arc' work? tlvp <mPiOsUcB.EtLlLvEp@att.net> - 2014-02-28 03:47 -0500
                Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2014-03-01 00:30 -0800
          Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2014-04-29 13:10 -0700
  Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2014-05-02 06:29 -0700
    Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2014-05-08 02:21 -0700

csiph-web