Circular arc approximation by cubic Bezier curve

From JSXGraph Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Approximating a circular by a single Bezier curve only is sufficiently exakt if the arc is less or equal than a quarter circle.

The underlying JavaScript code

var brd = JXG.JSXGraph.initBoard('jxgbox',{axis:false,boundingbox:[-2,2,2,-2],keepaspectratio:true});

var M = brd.create('point', [0,0], {name:'M'});
var C = brd.create('point', [0,-1], {name:'D'});
var c = brd.create('circle', [M,C], {strokeWidth:1});
var A = brd.create('glider', [1,0,c], {name:'A'});
var B = brd.create('glider', [0,1,c], {name:'B'});

var k = function(M, A, B) {
    var ax = A.X()-M.X(),
        ay = A.Y()-M.Y(),
        bx = B.X()-M.X(),
        by = B.Y()-M.Y(),
        d, r;
    r = M.Dist(A);
    d = Math.sqrt((ax+bx)*(ax+bx) + (ay+by)*(ay+by));
    if (JXG.Math.Geometry.rad(A,M,B)>Math.PI) { d *= -1; }

    if (Math.abs(by-ay)>JXG.Math.eps) {
        return (ax+bx)*(r/d-0.5)*8.0/3.0/(by-ay);
    } else {
        return (ay+by)*(r/d-0.5)*8.0/3.0/(ax-bx);
    }
};
var P1 = brd.create('point', [
            function(){ return A.X()-k(M,A,B)*(A.Y()-M.Y()); },
            function(){ return A.Y()+k(M,A,B)*(A.X()-M.X()); }
], {color:'blue'});
var P2 = brd.create('point', [
            function(){ return B.X()+k(M,A,B)*(B.Y()-M.Y()); },
            function(){ return B.Y()-k(M,A,B)*(B.X()-M.X()); }
], {color:'blue'});

var b = brd.create('curve', JXG.Math.Numerics.bezier([A,P1,P2,B]), 
               {strokecolor:'black', strokeOpacity:1, strokeWidth:3}); 


var l1 = brd.create('segment', [A,P1], {dash:2});
var l2 = brd.create('segment', [B,P2], {dash:2});