Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #1731 > unrolled thread
| Started by | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| First post | 2013-11-20 23:23 -0800 |
| Last post | 2016-04-19 02:54 -0700 |
| Articles | 20 on this page of 35 — 5 participants |
Back to article view | Back to comp.lang.postscript
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> - 2019-02-02 16:19 -0800
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
Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2016-04-01 15:28 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-02 21:35 -0700
Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2016-04-03 13:54 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-18 21:40 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-19 15:04 -0700
Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2016-04-20 02:06 -0700
Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2016-04-20 05:18 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-22 00:40 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-22 11:32 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-23 20:49 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-23 22:46 -0700
Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2016-04-24 04:01 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-30 21:47 -0700
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-05-01 02:59 -0700
Re: How does 'arc' work? Scott Hemphill <hemphill@hemphills.net> - 2016-04-03 10:40 -0400
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-05 21:48 -0700
Re: How does 'arc' work? Scott Hemphill <hemphill@hemphills.net> - 2016-04-06 10:37 -0400
Re: How does 'arc' work? luser- -droog <mijoryx@yahoo.com> - 2016-04-07 23:59 -0700
Re: How does 'arc' work? jdaw1 <jdawiseman@gmail.com> - 2016-04-19 02:54 -0700
Page 1 of 2 [1] 2 Next page →
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-11-20 23:23 -0800 |
| Subject | How does 'arc' work? |
| Message-ID | <356283f9-d422-4515-8bd6-5ad0cf625f07@googlegroups.com> |
This may seem like a silly question to some. But how does 'arc' construct curves to approximate the arc section? I know you can make a full circle with 4 Bezier curves whose control points are arranged on a square. (ASCII ART: * o * * * o o * * * o * ) So for smaller intervals, do you just trim-up this template? Constructing as many full quadrants as necessary and smaller pieces for the ends? Say you want to do: (0,0) [45..180] r=1. You want the -x,+y quadrant in full, * o * o But then, for the partial piece in +x,+y, hm, I suppose you actually have to compute the Bezier approximation, huh? x = r cos t y = r sin t 45 <= t <= 90 So the end points, of course, are x = 1 cos 45 = sqrt 2 y = 1 sin 45 = sqrt 2 x = 1 cos 90 = 0 y = 1 sin 90 = 1 and the control points are ...
[toc] | [next] | [standalone]
| From | bugbear <bugbear@trim_papermule.co.uk_trim> |
|---|---|
| Date | 2013-11-21 14:05 +0000 |
| Message-ID | <-5-dndB5LsWhjhPPnZ2dnUVZ8tWdnZ2d@brightview.co.uk> |
| In reply to | #1731 |
luser- -droog wrote: > This may seem like a silly question to some. But how does 'arc' > construct curves to approximate the arc section? > > I know you can make a full circle with 4 Bezier curves > whose control points are arranged on a square. (ASCII ART: > > * o * > * * > o o > * * > * o * ) > You can *approximate* a full circle with 4 Bezier curves. Depending on the final size of the circle (and thus the pixel error it engenders) you might want to use more than 4 beziers. BugBear
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-12-01 04:03 -0800 |
| Message-ID | <d835ec42-1a64-4128-8efd-b77c2e9624d6@googlegroups.com> |
| In reply to | #1732 |
On Thursday, November 21, 2013 8:05:46 AM UTC-6, bugbear wrote: > luser- -droog wrote: > > > This may seem like a silly question to some. But how does 'arc' > > > construct curves to approximate the arc section? > > > > > > I know you can make a full circle with 4 Bezier curves > > > whose control points are arranged on a square. (ASCII ART: > > > > > > * o * > > > * * > > > o o > > > * * > > > * o * ) > > > > > > > You can *approximate* a full circle with 4 Bezier curves. > > > > Depending on the final size of the circle (and thus the pixel > > error it engenders) you might want to use more than 4 beziers. > > > > BugBear Thank you, that is useful. I could perform the calculations in device coordinates with a little extra effort. I'm almost more afraid of overkill than deficient precision. The later can more easily detected by eye. :) I must confess, I'm usually afraid of your posts, BugBear! A few times in the past, they have totally blown my design apart, and caused lots of extra (ultimately-well-worthwhile) hard work. Keep it up, brother! :)
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2013-11-23 15:06 -0800 |
| Message-ID | <a8c2ee20-a057-4055-8e35-cda59526aec7@googlegroups.com> |
| In reply to | #1731 |
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.
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-12-01 03:48 -0800 |
| Message-ID | <2bebfa0f-c416-44c3-aca4-2b0afbead55e@googlegroups.com> |
| In reply to | #1733 |
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.
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-12-01 03:58 -0800 |
| Message-ID | <dd7907b8-824f-4cfa-b797-08a99d902404@googlegroups.com> |
| In reply to | #1743 |
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. :) - sleepy
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-12-10 23:02 -0800 |
| Message-ID | <55a3bc70-ad65-4552-9c33-c5cbd27c8c37@googlegroups.com> |
| In reply to | #1744 |
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 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.
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-12-11 00:17 -0800 |
| Message-ID | <77838e40-eac4-46cb-8372-4e642ad0f387@googlegroups.com> |
| In reply to | #1747 |
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
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-12-11 00:20 -0800 |
| Message-ID | <b17b149f-31f5-479e-a5e4-4b3f46d43d52@googlegroups.com> |
| In reply to | #1748 |
On Wednesday, December 11, 2013 2:17:35 AM UTC-6, luser- -droog wrote:
> 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)
Dammit. y0 = sin(a) of course.
> 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
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2013-12-11 01:37 -0800 |
| Message-ID | <17037d59-7901-4533-b15d-7c8da15ec595@googlegroups.com> |
| In reply to | #1749 |
On Wednesday, December 11, 2013 2:20:11 AM UTC-6, luser- -droog wrote:
> On Wednesday, December 11, 2013 2:17:35 AM UTC-6, luser- -droog wrote:
> > > > 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 = [sin](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
> >
It can be done with half the transforms by using 3 matrices.
> > 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
> >
There's a bug here. Trimming 360 means 360 become 0 and a full
circle won't draw anything. So bump the 360s up to 720, or just
first one.
> > 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
These are drawn in the wrong order. It results in
criss-crosses through the center when drawing a circle.
S.b.:
6 copy
3 2 roll add exch arc
sub arc
> > }{ pop
> > % draw single bezier
> > arcbez
> > } ifelse
> > } def
[toc] | [prev] | [next] | [standalone]
| From | tlvp <mPiOsUcB.EtLlLvEp@att.net> |
|---|---|
| Date | 2014-02-28 03:47 -0500 |
| Message-ID | <ip2u6i82k9ds.agidm5snj8d1$.dlg@40tude.net> |
| In reply to | #1749 |
On Wed, 11 Dec 2013 00:20:11 -0800 (PST), luser- -droog wrote: >> x0 = cos(a) >> >> y0 = cos(a) > > Dammit. y0 = sin(a) of course. Ah, the perils of "cut, paste, and edit", when we forget the "edit" part :-) . Cheers, -- tlvp -- Avant de repondre, jeter la poubelle, SVP.
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2014-03-01 00:30 -0800 |
| Message-ID | <22433e46-3fc1-4848-b82d-8791ac084d3b@googlegroups.com> |
| In reply to | #1799 |
On Friday, February 28, 2014 2:47:58 AM UTC-6, tlvp wrote: > On Wed, 11 Dec 2013 00:20:11 -0800 (PST), luser- -droog wrote: > > >> x0 = cos(a) > >> y0 = cos(a) > > > > Dammit. y0 = sin(a) of course. > > Ah, the perils of "cut, paste, and edit", when we forget the "edit" part > > :-) . Cheers, -- tlvp > Very generous, but I'm pretty sure I typed that. I can get a little "lyxdexic" in the wee hours. -- call me the space cowboy.
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2014-04-29 13:10 -0700 |
| Message-ID | <6b206906-812c-438e-95bd-537f8fc72a8c@googlegroups.com> |
| In reply to | #1747 |
> 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. If you do that for the 90° case, you’d get a result of (√2–1)×4/3 ≈ 0.55228475, also close the PostScript value of 0.552. For the 90° case I have a really good spreadsheet with all the cases you might want. My contact details are at http://www.jdawiseman.com/author.html — send me an email and I’ll send .xls.
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2019-02-02 16:19 -0800 |
| Message-ID | <efa1d942-4e9e-4690-b0ed-ca32941569f5@googlegroups.com> |
| In reply to | #1733 |
A function has been written for those wishing to render a mathematical in few Bézier cubics. Details in https://groups.google.com/forum/#!topic/comp.lang.postscript/3RIq0Jnwrbo
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2014-05-02 06:29 -0700 |
| Message-ID | <de0e8bc0-b615-409b-aa97-733ea641497c@googlegroups.com> |
| In reply to | #1731 |
You have forced me to do some simple work on this, and the answer is actually quite easy. http://www.jdawiseman.com/2014/Bezier_part_circle_20140502.nb http://www.jdawiseman.com/2014/Bezier_part_circle_20140502.pdf Justify that the inner control points are a distance away from the ends of (4/3)×Tan[Angle÷4].
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2014-05-08 02:21 -0700 |
| Message-ID | <f95b1582-18f3-4c62-b0fb-44a35f71f7f7@googlegroups.com> |
| In reply to | #1869 |
Slightly improved, showing the size of the maximum radius error (varying, for small angles, as the sixth power of that angle). http://www.jdawiseman.com/2014/Bezier_part_circle_20140508.nb http://www.jdawiseman.com/2014/Bezier_part_circle_20140508.pdf
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2016-04-01 15:28 -0700 |
| Message-ID | <2240fb7d-ff33-4281-b837-a2b119198179@googlegroups.com> |
| In reply to | #1890 |
All the above reasoning was about 90° angles. What about smaller angles? For the Bézier curve, obviously the two outer control points are at the y=sin() x=cos() ends of the segment of the circle. Obviously the two inner control points are at an angle that is tangent to that segment of the circle. This leaves one missing parameter: how far away are the inner control points? For 90° of the unit circle, 0.552, as discussed above. I didn’t realise until recently that 90° is a special case: extrapolating the distances for smaller angles to 90° would give 0.552285, the 0.552 crossover happening near 89.9582°. For code to generate numbers, and subsequent analysis, see http://www.jdawiseman.com/2016/20160401_bezier_arcs.ps http://www.jdawiseman.com/2016/20160401_bezier_arcs.xlsx Comment and improvements welcomed. Do any readers of this forum know the actual angle→distance formula?
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2016-04-02 21:35 -0700 |
| Message-ID | <0fc50e67-e520-40cd-b841-f458f58c9290@googlegroups.com> |
| In reply to | #2481 |
On Friday, April 1, 2016 at 5:28:23 PM UTC-5, jdaw1 wrote: > All the above reasoning was about 90° angles. What about smaller angles? > > For the Bézier curve, obviously the two outer control points are at the y=sin() x=cos() ends of the segment of the circle. Obviously the two inner control points are at an angle that is tangent to that segment of the circle. This leaves one missing parameter: how far away are the inner control points? > > For 90° of the unit circle, 0.552, as discussed above. I didn’t realise until recently that 90° is a special case: extrapolating the distances for smaller angles to 90° would give 0.552285, the 0.552 crossover happening near 89.9582°. > > For code to generate numbers, and subsequent analysis, see > http://www.jdawiseman.com/2016/20160401_bezier_arcs.ps > http://www.jdawiseman.com/2016/20160401_bezier_arcs.xlsx > > Comment and improvements welcomed. > > Do any readers of this forum know the actual angle→distance formula? You did see this message of mine, right? https://groups.google.com/d/msg/comp.lang.postscript/YiuM6lj5ngY/4Lo9AW0M2xgJ Aside from the cos/sin bungle, what do you need that these formulas don't get you? x0 = cos(a) y0 = sin(a) x1 = (4 - cos(a)) / 3 y1 = ((1 - cos(a))(cos(a) - 3)) / (3*sin(a)) x2 = x1 y2 = -y1 x3 = x0 y3 = -y0
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2016-04-03 13:54 -0700 |
| Message-ID | <c5b7ac2f-3af9-41f7-a0a4-00396e69944a@googlegroups.com> |
| In reply to | #2483 |
On Sunday, 3 April 2016 05:35:24 UTC+1, luser- -droog wrote: > Aside from the cos/sin bungle, what do you need that these formulas > don't get you? > > x0 = cos(a) > y0 = sin(a) > x1 = (4 - cos(a)) / 3 > y1 = ((1 - cos(a))(cos(a) - 3)) / (3*sin(a)) > x2 = x1 > y2 = -y1 > x3 = x0 > y3 = -y0 Are they correct? I am expecting, with an angle of π/2 = 90°, that Sqrt[(x0-x1)^2+(y0-y1)^2] should be about 0.552. I think your formula returns 2×Sqrt[13]/3 ≈ 2.4037. Even with a = π/4 = 45°, it returns a distance of 1.09565. Or have I made an error?
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2016-04-18 21:40 -0700 |
| Message-ID | <c16e0fb9-1e4e-4eef-93be-344ee3f29c9d@googlegroups.com> |
| In reply to | #2486 |
On Sunday, April 3, 2016 at 3:54:55 PM UTC-5, jdaw1 wrote: > On Sunday, 3 April 2016 05:35:24 UTC+1, luser- -droog wrote: > > > Aside from the cos/sin bungle, what do you need that these formulas > > don't get you? > > > > x0 = cos(a) > > y0 = sin(a) > > x1 = (4 - cos(a)) / 3 > > y1 = ((1 - cos(a))(cos(a) - 3)) / (3*sin(a)) > > x2 = x1 > > y2 = -y1 > > x3 = x0 > > y3 = -y0 > > Are they correct? I am expecting, with an angle of π/2 = 90°, that Sqrt[(x0-x1)^2+(y0-y1)^2] should be about 0.552. I think your formula returns 2×Sqrt[13]/3 ≈ 2.4037. Even with a = π/4 = 45°, it returns a distance of 1.09565. > > Or have I made an error? I'm not sure! Referring to this file of yours: http://www.jdawiseman.com/2014/Bezier_part_circle_20140508.pdf I'm not sure I understand it. Does the "Knots" stuff accurately model the Bezier interpolation? Empirically, my code seems to draw things that look like circular arcs to me. And my math-guru spent a few days with the equations and came up with the same results. The derivation only worries about the middle point of the curve, where the naïve recursive deCasteljau subdivision will later chop the curve in twain and select the point as the join. We then just assume by symmetry that further subdivision points will be on the same arc. I also don't see in your notes any easy formula that I can grab and apply to the problem of calculating the control points given theta. On the other hand, based on the outputs from Scott's program, it appears my lengths are fairly consistent in being close to double the "desired" measure. So it's probably worthwhile to try scaling my tangent lengths and compare outputs. Maybe my circles are not as pretty as they might be...
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.postscript
csiph-web