Circular arc approximation by cubic Bezier curve

From JSXGraph Wiki
Jump to: navigation, search

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});