Alasdair
Alasdair

Reputation: 1354

JSXGraph: intersections and otherintersection between line and general conic section?

Short version: If E is a general conic section, and L is a line through it, I want something like:

P = board.create('intersection',[L,E,0]);
Q = board.create('otherintersection',[L,E,P]);

except that otherintersection doesn't seem to work unless E is a circle.

Long version: The attached diagram shows what I'm doing. I have an internal ellipse, and an outer conic section E, which here is an ellipse, but could be any other. P glides on the outer curve, and its tangents to the inner ellipse are created.

Two ellipses and tangents

The problem is that I want to name the other intersections where the tangent lines meet the outer ellipse.

If the outer curve was a circle, I could use otherintersection, but I can't here, even though I can find the intersection points at both ends. Here is the standard geometric method I used:

  1. Draw the circle C1 centred at focus f1 and whose radius is the length of the major axis.
  2. Draw the circle C2 centred at P going through focus f2.
  3. Find the intersection points M1 and M2 of C1 and C2.
  4. The tangent lines are the perpendicular bisectors from P to the lines f2-M1 and f2-M2.

If the tangent lines are T1 and T2 say, I can find the intersections with the outer conic section E with

t10 = board.create('intersection',[T1,E,0]);
t11 = board.create('intersection',[T1,E,1]);
t20 = board.create('intersection',[T2,E,0]);
t21 = board.create('intersection',[T2,E,1]);

Because all of this is done numerically in JSXGraph, neither of the end points of a tangent may be exactly equal to P. So I can't simply ask which of the two endpoints is not P. I've tried finding out which endpoint is further from P, but I can't get this to work:

if (P.Dist(t10) > P.Dist(t11)) {
   t10.setAttribute({name:'Q'});
} else {
   t11.setAttribute({name:'Q'});
}

This only works for half the curve. I've checked lengths and distances with outputs to console.log, and clearly something is not working. But I don't know how to fix it.

I hope I've made my problem clear. Is this enough information?

Upvotes: 0

Views: 70

Answers (1)

Alfred Wassermann
Alfred Wassermann

Reputation: 2323

Indeed, as of JSXGraph version v1.6.2, otherintersection handles only combinations circle / line or circle / circle. It is an excellent suggestion to add the cases line / conic, conic / circle and conic / conic. Maybe, this this will make it already into the upcoming v1.7.0.

A workaround until then is the following code. Your construction to generate the above image (but less beautiful) including the tangent lines t1 and t2 looks something like this:

    const board = JXG.JSXGraph.initBoard('jxgbox', {
      boundingbox: [-7, 7, 7, -7], axis: true
    });

    var f1 = board.create('point', [1, 0], { name: 'f_1' });
    var f2 = board.create('point', [-1, 0], { name: 'f_2' });
    var A = board.create('point', [0, 1], { name: 'A' });
    var inner = board.create('ellipse', [f1, f2, A]);

    var P = board.create('point', [-3, 4], { name: 'P' });
    var outer = board.create('ellipse', [[-3, -3], [3, 3], P]);

    var c1 = board.create('circle', [f1, () => (f1.Dist(A) + f2.Dist(A))], { strokeColor: '#bbb', dash: 2 });
    var c2 = board.create('circle', [P, f2], { strokeColor: '#bbb', dash: 2 });

    var M1 = board.create('intersection', [c1, c2], { name: 'M1', size: 2 });
    var M2 = board.create('otherintersection', [c1, c2, M1], { name: 'M2', size: 2 });

    var l1 = board.create('line', [f2, M1], { strokeWidth: 1, dash: 3, visible: false });
    var l2 = board.create('line', [f2, M2], { strokeWidth: 1, dash: 3, visible: false });

    var a1 = board.create('midpoint', [f2, M1], { size: 2, name: '' });
    var a2 = board.create('midpoint', [f2, M2], { size: 2, name: '' });

    var t1 = board.create('perpendicular', [l1, a1]);
    var t2 = board.create('perpendicular', [l2, a2]);

Now, the "other" intersection points of t1 and t2 with outer can be constructed with this code:

    var otherIntersection = function (el1, el2, other) {
      var c = JXG.Math.Geometry.meetCurveLine(el1, el2, 0, el1.board);

      if (
        Math.abs(other.X() - c.usrCoords[1]) > 0.001 ||
        Math.abs(other.Y() - c.usrCoords[2]) > 0.001 ||
        Math.abs(other.Z() - c.usrCoords[0]) > 0.001
      ) {
        return c.usrCoords;
      }

      return JXG.Math.Geometry.meetCurveLine(el1, el2, 1, el1.board).usrCoords;
    };

    var other1 = board.create('point', [() => otherIntersection(outer, t1, P)], { name: 'Q_1' });
    var other2 = board.create('point', [() => otherIntersection(outer, t2, P)], { name: 'Q_2' });

See it live at https://jsfiddle.net/0f5pgrw7/2/

Upvotes: 0

Related Questions