Search code examples
functiondistancejsxgraph

JSXGraph: Distance between points is not updating


Short version How do I enter a circle whose radius is a function of the distances between three moveable points? For example:

board.create('circle',[A,A.Dist(B)+A.Dist(C)]);

As the points are moved around, the centre changes, but the radius stays fixed.


Longer version I am trying to write a function to compute tangents to an ellipse from an external point, using the construction given at

http://whistleralley.com/conics/conic_construction/tangent_to_conic/

Among other things, this requires me to produce a circle, centred at a focus, whose radius is equal to the ellipse's major axis. This is (part of) what I have so far:

 var f1 = board.create('point',[4,0],{name:f1});
 var f2 = board.create('point',[-4,0],{name:f2});
 var A = board.create('point',[0,3]);              
 var ell = board.create('ellipse',[f1,f2,A]);

 var P = board.create('point',[-6,6]);
 var c2 = board.create('circle',[f2, A.Dist(f1)+A.Dist(f2)]);

This works fine until I start moving points around - if the initial points which define the ellipse are changed, the circle's radius is not changed. Its center follows f2 wherever that point is moved, but the radius is not changed. Clearly this is because the radius needs to be defined as a function. But how? This, for example, doesn't work:

var c2 = board.create('circle',[f2, function(f1,f2,A){return A.Dist(f1)+A.Dist(f2)}]);

This throws a type-error (in the Console): "TypeError: Cannot read properties of undefined (reading 'Dist')".

I could write an ellipse function by hand (using curve), using parameters given by sliders. But that seems like overkill, when there is already an ellipse function.

I also could write three listening functions:

A.on('drag', ()=> {   });
f1.on('drag', ()=> {   });
f2.on('drag', ()=> {   });

which update the radius whenever one of those points is moved. But again, this seems like overkill.

What is my best option here? Many thanks!


Solution

  • In your first attempt

    var c2 = board.create('circle',[f2, A.Dist(f1)+A.Dist(f2)]);
    

    the radius of the circle c2 is set to the static value A.Dist(f1)+A.Dist(f2), which is evaluated when board.create('circle',...) is executed. In order to make the radius dynamic, one simple has to supply a function wich returns this value, like

    var c2 = board.create('circle',[f2, () => A.Dist(f1)+A.Dist(f2)]);
    

    Then the distance is evaluated at each update of the board. Here is the full code (additionally the point names are strings):

     var f1 = board.create('point',[4,0],{name:'f1'});
     var f2 = board.create('point',[-4,0],{name:'f2'});
     var A = board.create('point',[0,3], {name: 'A'});              
     var ell = board.create('ellipse',[f1,f2,A]);
    
     var P = board.create('point',[-6,6], {name: 'P'});
     var c2 = board.create('circle',[f2, () => A.Dist(f1)+A.Dist(f2)]);
    

    See it live at https://jsfiddle.net/p8suedgt/