add cube quartic euqation

This commit is contained in:
mkwiser 2014-09-05 08:34:45 +08:00
parent cfa4f83e37
commit 51e90c8f32
8 changed files with 487 additions and 10 deletions

72
demo/js/math.js Normal file
View File

@ -0,0 +1,72 @@
/**
* @file math.js
* @author mengke01
* @date
* @description
* 方程运算
*/
define(
function(require) {
var quadraticEquation = require('math/quadraticEquation');
var cubeEquation = require('math/cubeEquation');
var quarticEquation = require('math/quarticEquation');
var bezierQuadraticEquation = require('math/bezierQuadraticEquation');
var bezierCubeEquation = require('math/bezierCubeEquation');
var bezierQuarticEquation = require('math/bezierQuarticEquation');
var entry = {
/**
* 初始化
*/
init: function () {
console.log(quadraticEquation(1, 0, 1));
console.log(bezierQuadraticEquation(1, 0, 1));
console.log('--------------------------------');
console.log(quadraticEquation(1, -2, 1));
console.log(bezierQuadraticEquation(1, -2, 1));
console.log('--------------------------------');
console.log(cubeEquation(1, 0, 0, 1));
console.log(bezierCubeEquation(1, 0, 0, 1));
console.log('--------------------------------');
console.log(cubeEquation(1, 0, 0, -1));
console.log(bezierCubeEquation(1, 0, 0, -1));
console.log('--------------------------------');
console.log(quarticEquation(1, 0, 0, 0, 1));
console.log(bezierQuarticEquation(1, 0, 0, 0, 1));
console.log('--------------------------------');
console.log(quarticEquation(1, 0, 0, 0, -1));
console.log(bezierQuarticEquation(1, 0, 0, 0, -1));
}
};
entry.init();
return entry;
}
);

25
demo/math.html Normal file
View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试render</title>
<script src="http://s1.bdstatic.com/r/www/cache/ecom/esl/1-8-2/esl.js"></script>
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>
<script>
require.config({
baseUrl: '../src',
paths: {
demo: '../demo/js',
}
});
define('jquery', $);
</script>
<script>
require(['demo/math']);
</script>
</body>
</html>

View File

@ -0,0 +1,40 @@
/**
* @file bezierCubeEquation.js
* @author mengke01
* @date
* @description
* 求解三次方程贝塞尔根
*/
define(
function(require) {
var cubeEquation = require('./cubeEquation');
/**
* 求解二次方程
*
* @param {number} a a系数
* @param {number} b b系数
* @param {number} c c系数
* @param {number} d d系数
* @return {Array} 系数解
*/
function bezierCubeEquation(a, b, c, d) {
var result = cubeEquation(a, b, c, d);
if(!result) {
return result;
}
var filter = result.filter(function(item) {
return item >= 0 && item <= 1;
});
return filter.length
? filter
: false;
}
return bezierCubeEquation;
}
);

View File

@ -3,7 +3,7 @@
* @author mengke01
* @date
* @description
* 求解二次贝塞尔方程
* 求解二次方程贝塞尔根
*/
define(
@ -15,16 +15,22 @@ define(
* 求解二次方程
*
* @param {number} a a系数
* @param {[type]} b b系数
* @param {[type]} c c系数
* @param {number} b b系数
* @param {number} c c系数
* @return {Array} 系数解
*/
function bezierQuadraticEquation(a, b, c) {
var result = quadraticEquation(a, b, c);
return result
? result.filter(function(item) {
return item >= 0 && item <= 1;
})
if(!result) {
return result;
}
var filter = result.filter(function(item) {
return item >= 0 && item <= 1;
});
return filter.length
? filter
: false;
}

View File

@ -0,0 +1,42 @@
/**
* @file bezierQuarticEquation.js
* @author mengke01
* @date
* @description
* 求解四次方程贝塞尔根
*/
define(
function(require) {
var quarticEquation = require('./quarticEquation');
/**
* 求解二次方程
*
* @param {number} a a系数
* @param {number} b b系数
* @param {number} c c系数
* @param {number} d d系数
* @param {number} e e系数
* @return {Array} 系数解
*/
function bezierQuarticEquation(a, b, c, d, e) {
var result = quarticEquation(a, b, c, d, e);
if(!result) {
return result;
}
var filter = result.filter(function(item) {
return item >= 0 && item <= 1;
});
return filter.length
? filter
: false;
}
return bezierQuarticEquation;
}
);

98
src/math/cubeEquation.js Normal file
View File

@ -0,0 +1,98 @@
/**
* @file cubeEquation.js
* @author mengke01
* @date
* @description
* 三次方程求解仅给出实根部分
* see:
* http://www.99cankao.com/algebra/cubic-equation.php
*
* 盛金公式判别法
当A=B=0方程有一个三重实根
当Δ=B^24AC>0方程有一个实根和一对共轭虚根
当Δ=B^24AC=0方程有三个实根其中有一个二重根
当Δ=B^24AC<0方程有三个不相等的实根
*/
define(
function(require) {
var quadraticEquation = require('./quadraticEquation');
/**
* 求解三次方程
*
* @param {number} a a系数
* @param {number} b b系数
* @param {number} c c系数
* @param {number} d d系数
* @return {Array} 解数组仅给出实根部分
*/
function cubeEquation(a, b, c, d) {
if (a == 0) {
return quadraticEquation(b, c, d);
}
if (d == 0) {
return quadraticEquation(a, b, c);
}
if(a != 1) {
b /= a;
c /= a;
d /= a;
}
var disc, q, r, dum1, s, t, term1, r13;
q = (3.0 * c - (b * b)) / 9.0;
r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b));
r /= 54.0;
disc = q * q * q + r * r;
term1 = (b / 3.0);
// one root real, two are complex
if (disc > 0) {
s = r + Math.sqrt(disc);
s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0)));
t = r - Math.sqrt(disc);
t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0)));
return [-term1 + s + t];
//r1 = -term1 + s + t;
// term1 += (s + t) / 2.0;
//r3 = dataForm.x2Re.value = -term1;
// term1 = Math.sqrt(3.0) * (-t + s) / 2;
// i2 = term1;
// i3 = -term1;
}
// The remaining options are all real
// i2 = 0;
// i3 = 0;
if (disc == 0) { // All roots real, at least two are equal.
r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0)));
var r1 = -term1 + 2.0 * r13;
var r2 = r3 = -(r13 + term1);
return r1 == r2 ? r1 : [r1, r2];
}
// Only option left is that all roots are real and unequal (to get here, q < 0)
q = -q;
dum1 = q * q * q;
dum1 = Math.acos(r / Math.sqrt(dum1));
r13 = 2.0 * Math.sqrt(q);
var r1 = -term1 + r13 * Math.cos(dum1 / 3.0);
var r2 = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0);
var r3 = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0);
return [r1, r2, r3];
}
return cubeEquation;
});

View File

@ -13,8 +13,8 @@ define(
* 求解二次方程
*
* @param {number} a a系数
* @param {[type]} b b系数
* @param {[type]} c c系数
* @param {number} b b系数
* @param {number} c c系数
* @return {Array} 系数解
*/
function quadraticEquation(a, b, c) {
@ -24,7 +24,11 @@ define(
}
if(b == 0) {
if(a | c <= 0) {
if(c == 0) {
return [0];
}
if(a > 0 && c < 0 || a < 0 && c > 0) {
var x2 = Math.sqrt(-c / a);
return [x2, -x2];
}

190
src/math/quarticEquation.js Normal file
View File

@ -0,0 +1,190 @@
/**
* @file quarticEquation.js
* @author mengke01
* @date
* @description
* 一元四次方程求解仅给出实根部分
* see:
* http://www.99cankao.com/algebra/quartic-equation.php
*/
define(
function(require) {
var cubeEquation = require('./cubeEquation');
/**
* 求解四次方程
*
* @param {number} a a系数
* @param {number} b b系数
* @param {number} c c系数
* @param {number} d d系数
* @param {number} e e系数
* @return {Array} 解数组仅给出实根部分
*/
function quarticEquation(a, b, c, d, e) {
if (a == 0) {
return cubeEquation(b, c, d, e);
}
if (e == 0) {
return cubeEquation(a, b, c, d);
}
if (a != 1) {
b /= a;
c /= a;
d /= a;
e /= a;
}
// Coefficients for cubic solver
var cb, cc, cd;
var discrim, q, r, RRe, RIm, DRe, DIm, dum1, ERe, EIm, s, t, term1, r13, sqR, y1, z1Re, z1Im, z2Re;
// 根据求根公式计算
cb = -c;
cc = -4.0 * e + d * b;
cd = -(b * b * e + d * d) + 4.0 * c * e;
if (cd == 0) {
// TODO
}
q = (3.0 * cc - (cb * cb)) / 9.0;
r = -(27.0 * cd) + cb * (9.0 * cc - 2.0 * (cb * cb));
r /= 54.0;
discrim = q * q * q + r * r;
term1 = (cb / 3.0);
if (discrim > 0) {
// 1 root real, 2 are complex
s = r + Math.sqrt(discrim);
s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0)));
t = r - Math.sqrt(discrim);
t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0)));
y1 = -term1 + s + t;
}
else {
if (discrim == 0) {
r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0)));
y1 = -term1 + 2.0 * r13;
}
else {
q = -q;
dum1 = q * q * q;
dum1 = Math.acos(r / Math.sqrt(dum1));
r13 = 2.0 * Math.sqrt(q);
y1 = -term1 + r13 * Math.cos(dum1 / 3.0);
}
}
// Determined y1, a real root of the resolvent cubic.
term1 = b / 4.0;
sqR = -c + term1 * b + y1;
RRe = RIm = DRe = DIm = ERe = EIm = z1Re = z1Im = z2Re = 0;
if (sqR >= 0) {
if (sqR == 0) {
dum1 = -(4.0 * e) + y1 * y1;
//D and E will be complex
if (dum1 < 0) {
z1Im = 2.0 * Math.sqrt(-dum1);
}
else {
z1Re = 2.0 * Math.sqrt(dum1);
z2Re = -z1Re;
}
}
else {
RRe = Math.sqrt(sqR);
z1Re = -(8.0 * d + b * b * b) / 4.0 + b * c;
z1Re /= RRe;
z2Re = -z1Re;
}
}
else {
RIm = Math.sqrt(-sqR);
z1Im = -(8.0 * d + b * b * b) / 4.0 + b * c;
z1Im /= RIm;
z1Im = -z1Im;
}
z1Re += -(2.0 * c + sqR) + 3.0 * b * term1;
z2Re += -(2.0 * c + sqR) + 3.0 * b * term1;
//At this point, z1 and z2 should be the terms under the square root for D and E
if (z1Im == 0) { // Both z1 and z2 real
if (z1Re >= 0) {
DRe = Math.sqrt(z1Re);
}
else {
DIm = Math.sqrt(-z1Re);
}
if (z2Re >= 0) {
ERe = Math.sqrt(z2Re);
}
else {
EIm = Math.sqrt(-z2Re);
}
}
else {
r = Math.sqrt(z1Re * z1Re + z1Im * z1Im);
r = Math.sqrt(r);
dum1 = Math.atan2(z1Im, z1Re);
dum1 /= 2; //Divide this angle by 2
ERe = DRe = r * Math.cos(dum1);
DIm = r * Math.sin(dum1);
EIm = -DIm;
}
// var real = [
// -term1 + (RRe + DRe) / 2,
// -(term1 + DRe / 2) + RRe / 2,
// -(term1 + RRe / 2) + ERe / 2,
// -(term1 + (RRe + ERe) / 2)
// ];
// var virtual = [
// (RIm + DIm) / 2,
// (-DIm + RIm) / 2,
// (-RIm + EIm) / 2,
// -(RIm + EIm) / 2
// ];
var real = [];
// check virtual root
if(0 == RIm + DIm) {
real.push(-term1 + (RRe + DRe) / 2);
}
if(0 == -DIm + RIm) {
real.push(-(term1 + DRe / 2) + RRe / 2);
}
if(0 == -RIm + EIm) {
real.push(-(term1 + RRe / 2) + ERe / 2);
}
if(0 == RIm + EIm) {
real.push(-(term1 + (RRe + ERe) / 2));
}
// 去重根
var unique = {};
var result = [];
for(var i = 0, l = real.length; i < l; i++) {
if (!unique[real[i]]) {
result.push(real[i]);
unique[real[i]] = true;
}
}
return result.length ? result : false;
}
return quarticEquation;
});