Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

JavaScriptでalgebra.jsを使って円と直線の交点を求める

algebra.jsという代数学ライブラリで連立方程式をときます。

背景

UnitaryJSで円と直線の方程式を出力できるようにしたのですが、そこから連立方程式を解くのに困りました。そこで以前algebra.jsというライブラリを触ったことを思い出してやってみた、という背景です。

準備

$ npm i algebra.js

なぜか私はインストールできませんでしたので公式 (algebra.js)から直接ダウンロードしました。

var algebra = require('algebra.js'); // 直接ダウンロードした場合はそのファイルへのリンク

連立方程式を解く

本題の連立方程式の解き方です。…実は、一般的なやり方ができません。というかわかりませんでした。すいません。強引にまず方程式をxについて解いて、それをもう一つに式に代入し、yについて解きます。あとはyの値を代入すればxの値もわかるという原理です。連立方程式に使われる文字がわからない場合、文字を羅列してから解くという手法をしなければなりません。

では実際に円と直線の交点を求めてみましょう。

var algebra = require('./algebra.min.js');

var circle = algebra.parse('x^2+y^2=4');
var line = algebra.parse('y=1');

// console.log(circle.eval({x: line.solveFor('x')}).solveFor('y')); // エラーが出ます
console.log(circle.eval({y: line.solveFor('y')}).solveFor('x'));

この方法、実は制約がつきます。直線の方程式を ax + by + c = 0 とします。例えば a が 0 つまり by + c = 0という形のとき、 x について解こうとするとエラーが出て、できません。そりゃそうです。

x について解けないのでもちろん円に代入してyについて解くことができません。

こうするとx、yが入っているかわかります。まあそこからx、yがそれぞれあるかに応じて処理わけるのとても面倒ですが。

var variable = [];
line.lhs.terms.forEach(function(items) {
    items.variables.forEach(function(item) {
        variable.push(item.variable);
    });
});

精度落としていいなら0.00001xと0.00001yを加えるなんていう邪道も…

そもそも直線の方程式なのかも保証できません。なかなか面倒です。