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


Groups > comp.lang.postscript > #1731 > unrolled thread

How does 'arc' work?

Started byluser- -droog <mijoryx@yahoo.com>
First post2013-11-20 23:23 -0800
Last post2016-04-19 02:54 -0700
Articles 20 on this page of 35 — 5 participants

Back to article view | Back to comp.lang.postscript


Contents

  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 →


#1731 — How does 'arc' work?

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-11-20 23:23 -0800
SubjectHow 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]


#1732

Frombugbear <bugbear@trim_papermule.co.uk_trim>
Date2013-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]


#1745

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-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]


#1733

Fromjdaw1 <jdawiseman@gmail.com>
Date2013-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]


#1743

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-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]


#1744

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-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]


#1747

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-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]


#1748

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-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]


#1749

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-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]


#1750

Fromluser- -droog <mijoryx@yahoo.com>
Date2013-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]


#1799

Fromtlvp <mPiOsUcB.EtLlLvEp@att.net>
Date2014-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]


#1803

Fromluser- -droog <mijoryx@yahoo.com>
Date2014-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]


#1867

Fromjdaw1 <jdawiseman@gmail.com>
Date2014-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]


#3333

Fromjdaw1 <jdawiseman@gmail.com>
Date2019-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]


#1869

Fromjdaw1 <jdawiseman@gmail.com>
Date2014-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]


#1890

Fromjdaw1 <jdawiseman@gmail.com>
Date2014-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]


#2481

Fromjdaw1 <jdawiseman@gmail.com>
Date2016-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]


#2483

Fromluser- -droog <mijoryx@yahoo.com>
Date2016-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]


#2486

Fromjdaw1 <jdawiseman@gmail.com>
Date2016-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]


#2530

Fromluser- -droog <mijoryx@yahoo.com>
Date2016-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