Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #1748
| 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> |
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 | Next — Previous in thread | Next in thread | Find similar
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