add cube quartic euqation
This commit is contained in:
parent
cfa4f83e37
commit
51e90c8f32
72
demo/js/math.js
Normal file
72
demo/js/math.js
Normal 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
25
demo/math.html
Normal 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>
|
40
src/math/bezierCubeEquation.js
Normal file
40
src/math/bezierCubeEquation.js
Normal 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;
|
||||
}
|
||||
);
|
||||
|
@ -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) {
|
||||
|
||||
if(!result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var filter = result.filter(function(item) {
|
||||
return item >= 0 && item <= 1;
|
||||
})
|
||||
});
|
||||
return filter.length
|
||||
? filter
|
||||
: false;
|
||||
}
|
||||
|
||||
|
42
src/math/bezierQuarticEquation.js
Normal file
42
src/math/bezierQuarticEquation.js
Normal 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
98
src/math/cubeEquation.js
Normal 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^2-4AC>0时,方程有一个实根和一对共轭虚根。
|
||||
当Δ=B^2-4AC=0时,方程有三个实根,其中有一个二重根。
|
||||
当Δ=B^2-4AC<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;
|
||||
});
|
@ -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
190
src/math/quarticEquation.js
Normal 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;
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user