How to use @mathigon/core - 10 common examples

To help you get started, we’ve selected a few @mathigon/core examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github mathigon / fermat.js / src / geometry.js View on Github external
function lineCircleIntersection(l, c) {
  const dx = l.p2.x - l.p1.x;
  const dy = l.p2.y - l.p1.y;
  const dr2 = square(dx) + square(dy);

  const cx = c.c.x;
  const cy = c.c.y;
  const D = (l.p1.x - cx) * (l.p2.y - cy) - (l.p2.x - cx) * (l.p1.y - cy);

  const disc = square(c.r) * dr2 - square(D);
  if (disc < 0) return [];  // No solution

  const xa = D * dy / dr2;
  const ya = -D * dx / dr2;
  if (nearlyEquals(disc, 0)) return [c.c.shift(xa, ya)];  // One solution

  const xb = dx * (dy < 0 ? -1 : 1) * Math.sqrt(disc) / dr2;
  const yb = Math.abs(dy) * Math.sqrt(disc) / dr2;
  return [c.c.shift(xa + xb, ya + yb), c.c.shift(xa - xb, ya - yb)];
}
github mathigon / fermat.js / src / geometry.js View on Github external
function circleCircleIntersection(c1, c2) {
  const d = Point.distance(c1.c, c2.c);

  if (d > c1.r + c2.r) return [];  // Circles are separate.
  if (d < Math.abs(c1.r - c2.r)) return [];  // One circles contains the other.
  if (nearlyEquals(d, 0) && nearlyEquals(c1.r,c2.r)) return [];  // Circles are the same.
  if (nearlyEquals(d, c1.r + c2.r)) return [new Line(c1.c, c2.c).midpoint]; // Circles touch.

  const a = (square(c1.r) - square(c2.r) + square(d)) / (2 * d);
  const b = Math.sqrt(square(c1.r) - square(a));

  const px = (c2.c.x - c1.c.x) * a / d + (c2.c.y - c1.c.y) * b / d + c1.c.x;
  const py = (c2.c.y - c1.c.y) * a / d - (c2.c.x - c1.c.x) * b / d + c1.c.y;
  const qx = (c2.c.x - c1.c.x) * a / d - (c2.c.y - c1.c.y) * b / d + c1.c.x;
  const qy = (c2.c.y - c1.c.y) * a / d + (c2.c.x - c1.c.x) * b / d + c1.c.y;

  return [new Point(px, py), new Point(qx, qy)]
}
github mathigon / fermat.js / src / geometry.js View on Github external
function circleCircleIntersection(c1, c2) {
  const d = Point.distance(c1.c, c2.c);

  if (d > c1.r + c2.r) return [];  // Circles are separate.
  if (d < Math.abs(c1.r - c2.r)) return [];  // One circles contains the other.
  if (nearlyEquals(d, 0) && nearlyEquals(c1.r,c2.r)) return [];  // Circles are the same.
  if (nearlyEquals(d, c1.r + c2.r)) return [new Line(c1.c, c2.c).midpoint]; // Circles touch.

  const a = (square(c1.r) - square(c2.r) + square(d)) / (2 * d);
  const b = Math.sqrt(square(c1.r) - square(a));

  const px = (c2.c.x - c1.c.x) * a / d + (c2.c.y - c1.c.y) * b / d + c1.c.x;
  const py = (c2.c.y - c1.c.y) * a / d - (c2.c.x - c1.c.x) * b / d + c1.c.y;
  const qx = (c2.c.x - c1.c.x) * a / d - (c2.c.y - c1.c.y) * b / d + c1.c.x;
  const qy = (c2.c.y - c1.c.y) * a / d + (c2.c.x - c1.c.x) * b / d + c1.c.y;

  return [new Point(px, py), new Point(qx, qy)]
}
github mathigon / fermat.js / src / expression.js View on Github external
function rewrite(expr, rule) {
  if (isString(expr) || isNumber(expr)) return expr;

  let [fn, ...args] = expr;
  args = args.map(a => rewrite(a, rule));

  // For addition and multiplications we need to match subsets of arguments, e.g.
  // `a + b + c` should match the rule `a + b`.
  let [ruleFn, ...ruleArgs] = rule[0];
  if ('+*'.includes(fn) && '+*'.includes(ruleFn) && args.length > ruleArgs.length) {
    for (let p of subsets(list(args.length), ruleArgs.length)) {
      let argsSubset = p.map(i => args[i]);  // The subset of args that match the rule.
      let argsOthers = args.filter((x, i) => !p.includes(i));  // All other args.

      let placeholders = match([fn, ...argsSubset], rule[0])[0];
      if (placeholders) {
        let argsReplaced = substitute(rule[1], placeholders);
        return flattenAssociative([fn, argsReplaced, ...argsOthers]);
      }
    }
    return [fn, ...args];
  }

  let placeholders = match([fn,...args], rule[0])[0];
  return placeholders ? substitute(rule[1], placeholders) : [fn, ...args];
}
github mathigon / textbooks / content / sequences / functions.ts View on Github external
export function quiz($step: Step) {
  const goals = list(14).map(x => 'blank-' + x).join(' ');
  $step.onScore(goals, () => {
    // Don't show confetti during page load.
    if ($step.isPageLoaded) $step.tools.confetti();
  });
}
github mathigon / fermat.js / src / expression.js View on Github external
function match(expr, target) {
  // Both expression and target are a number.
  if (isNumber(target)) {
    return (expr === target) ? [{}] : [];
  }

  if (isString(target)) {
    // Matches any constants (numbers)
    if (target[0] == 'c') {
      return isNumber(expr) ? [{[target]: expr}] : [];
    }

    // Matches any variables (strings)
    if (target[0] == 'v') {
      return isString(expr) ? [{[target]: expr}] : [];
    }

    // Match any other expressions
    return [{[target]: expr}];
  }

  // Check if functions are the same
  if (!isArray(expr)) return [];
  let [fn, ...args] = expr;
  if (fn != target[0]) return [];
  if (expr.length != target.length) return [];

  // Match all arguments of a function. Addition and multiplication can
  // match arguments in any order.
  if ('+*'.includes(expr[0])) {
    for (let a of permutations(args)) {
github mathigon / fermat.js / src / expression.js View on Github external
function mathML(expr) {
  // TODO Implement MathML for all operators.
  // TODO Distinguish between fractions and '÷'.

  if (isNumber(expr)) return ``;
  if (isString(expr)) return ``;

  const [fn, ...args] = expr;
  const argsStr = args.map(a => needsBrackets(a, fn) ? `` : mathML(a));

  switch(fn) {
    case 'sqrt': return ``;
    case '/': return ``;
    case '^': return ``;
    case '*': return argsStr.join('');
    case '+': return argsStr.join('');
    case '-': return argsStr.join('');
    default: return ``;
  }
}
github mathigon / fermat.js / src / expression.js View on Github external
function match(expr, target) {
  // Both expression and target are a number.
  if (isNumber(target)) {
    return (expr === target) ? [{}] : [];
  }

  if (isString(target)) {
    // Matches any constants (numbers)
    if (target[0] == 'c') {
      return isNumber(expr) ? [{[target]: expr}] : [];
    }

    // Matches any variables (strings)
    if (target[0] == 'v') {
      return isString(expr) ? [{[target]: expr}] : [];
    }

    // Match any other expressions
    return [{[target]: expr}];
  }

  // Check if functions are the same
  if (!isArray(expr)) return [];
github mathigon / textbooks / content / circles / functions.ts View on Github external
export function kepler($step: Step) {
  const N = 100;  // number of points
  const a = 120;  // semi-major axis (ry)
  const e = 0.5;  // eccentricity

  // BesselJ function - Table[BesselJ[i, i*0.5], {i, 0, 10}]
  const besselJ = [1, 0.242268, 0.114903, 0.060964, 0.0339957, 0.0195016,
    0.0113939, 0.006743, 0.00402867, 0.00242466, 0.0014678];

  const points = tabulate((n) => {
    const M = 2 * Math.PI * n / N;  // mean anomaly

    let E = M;  // eccentric anomaly
    for (let i = 1; i < 10; ++i) E += 2 / i * besselJ[i] * Math.sin(i * M);

    const th = 2 * Math.atan(Math.sqrt((1 + e) / (1 - e)) * Math.tan(E / 2));
    const r = a * (1 - e * e) / (1 + e * Math.cos(th));
    return Point.fromPolar(th, r).shift(220, 120);
  }, N + 1);

  const $orbit = $step.$('.orbit') as SVGView;
  const $earth = $step.$('.earth') as SVGView;
  const $sweep = $step.$('.sweep')!;
  const $play = $step.$('x-play-btn') as PlayBtn;

  $orbit.points = points;
github mathigon / fermat.js / src / expression.js View on Github external
function match(expr, target) {
  // Both expression and target are a number.
  if (isNumber(target)) {
    return (expr === target) ? [{}] : [];
  }

  if (isString(target)) {
    // Matches any constants (numbers)
    if (target[0] == 'c') {
      return isNumber(expr) ? [{[target]: expr}] : [];
    }

    // Matches any variables (strings)
    if (target[0] == 'v') {
      return isString(expr) ? [{[target]: expr}] : [];
    }

    // Match any other expressions
    return [{[target]: expr}];
  }

  // Check if functions are the same
  if (!isArray(expr)) return [];
  let [fn, ...args] = expr;
  if (fn != target[0]) return [];
  if (expr.length != target.length) return [];