POV-Ray : Newsgroups : povray.general : Bezier spline approximations to circles Server Time
31 Oct 2024 23:32:39 EDT (-0400)
  Bezier spline approximations to circles (Message 1 to 4 of 4)  
From: JimT
Subject: Bezier spline approximations to circles
Date: 22 Jan 2019 10:25:00
Message: <web.5c47356c36095c6fbe7517870@news.povray.org>
Just so it didn't get lost in an old post...

I was in a rush when I replied last time and didn't have this to hand. Second
installment.

If you want a Bezier Spline approximation to an arc of a circle subtending angle
theta at the centre, the four control points are

(1,0), (1,a), (cos(theta) + asin(theta),sin(theta) -
acos(theta)),(cos(theta),sin(theta))

where a = (8/3)(sin(theta/2) - sin(theta)/2)/(1-cos(theta))

As mentioned before, this is tangent to the circle at theta/2 as well as the
endpoints and outside the circle otherwise.  For theta = pi/2 the defect is
0.03% of the radius. For theta = pi it is 1.8%, still not bad, but for theta =
5pi/4 it is an unusable 7.6%.

Tweaking a to have the spline cross the circle twice reduces the error only to
about 70% of the value given and is probably not worth it.

If anyone wants code for a single segment Bezier Spline sphere sweep, I will
post it again, since the last time was years ago.


Post a reply to this message

From: Cousin Ricky
Subject: Re: Bezier spline approximations to circles
Date: 25 Jan 2019 16:09:09
Message: <5c4b7af5$1@news.povray.org>
On 2019-01-22 11:23 AM (-4), JimT wrote:
> If you want a Bezier Spline approximation to an arc of a circle subtending angle
> theta at the centre, the four control points are
> 
> (1,0), (1,a), (cos(theta) + asin(theta),sin(theta) -
> acos(theta)),(cos(theta),sin(theta))
> 
> where a = (8/3)(sin(theta/2) - sin(theta)/2)/(1-cos(theta))

Hmmm.  This is the formula for 'a' that I used for the ring shank cross 
section in GemCuts:

   #declare Gem__fn_Bezier_arc = function (x)
   { (8 * cos (x / 2) - 4 - 4 * cos (x)) / (3 * sin (x))
   }

Presumably, they are somehow the same formula, though I haven't figured 
out how to reduce one to the other.

> As mentioned before, this is tangent to the circle at theta/2 as well as the
> endpoints and outside the circle otherwise.  For theta = pi/2 the defect is
> 0.03% of the radius. For theta = pi it is 1.8%, still not bad, but for theta =
> 5pi/4 it is an unusable 7.6%.

My notes say that the curve deviates markedly from a circle if x > 90 
degrees (pi / 2), though I did not quantify the error.

> Tweaking a to have the spline cross the circle twice reduces the error only to
> about 70% of the value given and is probably not worth it.

For large angles I just use 2 segments.

I've actually tried multiple crossings to approximate a quadrant of a 
superquadric ellipse, but it required an arbitrary amount of fudging.  I 
do not have a general formula for this.  I also tried using two 45 
degree segments, but the result was horrible.

> If anyone wants code for a single segment Bezier Spline sphere sweep, I will
> post it again, since the last time was years ago.

There are two Object Collection modules that already do this for 
multiple segments: PointArrays and SphereSweep.


Post a reply to this message

From: JimT
Subject: Re: Bezier spline approximations to circles
Date: 20 Feb 2019 09:10:01
Message: <web.5c6d5ef876c96ecec97227110@news.povray.org>
Cousin Ricky <ric### [at] yahoocom> wrote:
> On 2019-01-22 11:23 AM (-4), JimT wrote:
> > If you want a Bezier Spline approximation to an arc of a circle subtending angle
> > theta at the centre, the four control points are
> >
> > (1,0), (1,a), (cos(theta) + asin(theta),sin(theta) -
> > acos(theta)),(cos(theta),sin(theta))
> >
> > where a = (8/3)(sin(theta/2) - sin(theta)/2)/(1-cos(theta))
>
> Hmmm.  This is the formula for 'a' that I used for the ring shank cross
> section in GemCuts:
>
>    #declare Gem__fn_Bezier_arc = function (x)
>    { (8 * cos (x / 2) - 4 - 4 * cos (x)) / (3 * sin (x))
>    }
>
Sorry I'm a month late. I didn't spot your post. And you probably won't spot
this.

I plotted them in Matlab to convince myself they were the same. Then I
multiplied top and bottom by sin(x/2)/cos(x/2). 1+cos(x) is 2cos^2(x/2) and
1-cos(x) is 2sin^2(x/2).


Post a reply to this message

From: Cousin Ricky
Subject: Re: Bezier spline approximations to circles
Date: 20 Feb 2019 23:13:11
Message: <5c6e2557$1@news.povray.org>
On 2019-02-20 10:06 AM (-4), JimT wrote:
> Cousin Ricky <ric### [at] yahoocom> wrote:
>> On 2019-01-22 11:23 AM (-4), JimT wrote:
>>> If you want a Bezier Spline approximation to an arc of a circle subtending angle
>>> theta at the centre, the four control points are
>>>
>>> (1,0), (1,a), (cos(theta) + asin(theta),sin(theta) -
>>> acos(theta)),(cos(theta),sin(theta))
>>>
>>> where a = (8/3)(sin(theta/2) - sin(theta)/2)/(1-cos(theta))
>>
>> Hmmm.  This is the formula for 'a' that I used for the ring shank cross
>> section in GemCuts:
>>
>>     #declare Gem__fn_Bezier_arc = function (x)
>>     { (8 * cos (x / 2) - 4 - 4 * cos (x)) / (3 * sin (x))
>>     }
>>
> Sorry I'm a month late. I didn't spot your post. And you probably won't spot
> this.
> 
> I plotted them in Matlab to convince myself they were the same. Then I
> multiplied top and bottom by sin(x/2)/cos(x/2). 1+cos(x) is 2cos^2(x/2) and
> 1-cos(x) is 2sin^2(x/2).

Good to know.  That's more trig than I can remember.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.