quartic equation

This commit is contained in:
kekee000
2014-09-05 20:14:59 +08:00
parent 51e90c8f32
commit 230f1470cd
6 changed files with 145 additions and 46 deletions

View File

@@ -13,9 +13,9 @@ define(
var cubeEquation = require('math/cubeEquation');
var quarticEquation = require('math/quarticEquation');
var bezierQuadraticEquation = require('math/bezierQuadraticEquation');
var bezierQ2Equation = require('math/bezierQ2Equation');
var bezierCubeEquation = require('math/bezierCubeEquation');
var bezierQuarticEquation = require('math/bezierQuarticEquation');
var bezierQ4Equation = require('math/bezierQ4Equation');
var entry = {
@@ -26,10 +26,10 @@ define(
console.log(quadraticEquation(1, 0, 1));
console.log(bezierQuadraticEquation(1, 0, 1));
console.log(bezierQ2Equation(1, 0, 1));
console.log('--------------------------------');
console.log(quadraticEquation(1, -2, 1));
console.log(bezierQuadraticEquation(1, -2, 1));
console.log(bezierQ2Equation(1, -2, 1));
console.log('--------------------------------');
@@ -46,10 +46,10 @@ define(
console.log(quarticEquation(1, 0, 0, 0, 1));
console.log(bezierQuarticEquation(1, 0, 0, 0, 1));
console.log(bezierQ4Equation(1, 0, 0, 0, 1));
console.log('--------------------------------');
console.log(quarticEquation(1, 0, 0, 0, -1));
console.log(bezierQuarticEquation(1, 0, 0, 0, -1));
console.log(bezierQ4Equation(1, 0, 0, 0, -1));

View File

@@ -9,7 +9,7 @@
define(
function(require) {
var isBezierRayCross = require('graphics/isBezierRayCross');
var isBezierCross = require('graphics/isBezierCross');
var entry = {
@@ -22,19 +22,6 @@ define(
var width = canvas.offsetWidth;
var height = canvas.offsetHeight;
// var points = [];
// [0, 1, 2, 3].forEach(function(i) {
// var p = {
// x: Math.floor(Math.random() * (width - 100) + 50),
// y: Math.floor(Math.random() * (height - 100) + 50)
// }
// points[i] = p;
// $($('.point').get(i)).css({
// left: p.x,
// top: p.y
// });
// });
var points = [
{
x: 130,
@@ -117,13 +104,25 @@ define(
ctx.quadraticCurveTo(points[4].x, points[4].y, points[5].x, points[5].y);
ctx.lineWidth = 1;
ctx.stroke();
//console.time('bezier');
var r = isBezierCross.apply(null, points);
//console.timeEnd('bezier');
//console.log(r);
if(r) {
ctx.beginPath();
r.forEach(function(item) {
ctx.arc(item.x, item.y, 4, 0, Math.PI * 2, true);
});
ctx.fill();
}
}
draw();
//var points = [{"x":79,"y":156},{"x":314,"y":227},{"x":74,"y":287},{"x":159,"y":116},{"x":32,"y":256},{"x":303,"y":290}];
//console.log(isBezierCross.apply(null, points));
}
};

View File

@@ -11,7 +11,9 @@ define(
function(require) {
var computeBoundingBox = require('./computeBoundingBox');
var isBoundingBoxCross = require('./isBoundingBoxCross');
var bezierQuadeEquation = require('../math/bezierQuadraticEquation');
var bezierQ2Equation = require('../math/bezierQ2Equation');
var bezierQ4Equation = require('../math/bezierQ4Equation');
var bezierCubeEquation = require('../math/bezierCubeEquation');
/**
* 矩阵乘
@@ -31,7 +33,6 @@ define(
*
* @param {Array.<number>} matrix1 一维矩阵
* @param {Array.<number>} matrix2 一维矩阵
* @param {number} scale 乘数算子
* @return {Array.<number>} 数组
*/
function minus(matrix1, matrix2) {
@@ -40,7 +41,18 @@ define(
});
}
/**
* 矩阵加
*
* @param {Array.<number>} matrix1 一维矩阵
* @param {Array.<number>} matrix2 一维矩阵
* @return {Array.<number>} 数组
*/
function plus(matrix1, matrix2) {
return matrix1.map(function(item, index) {
return item + matrix2[index];
});
}
/**
* 求两个bezier曲线的交点
@@ -79,35 +91,123 @@ define(
// 退化成一元二次方程
if(tmatrix[4] == 0) {
tResult = bezierQuadeEquation.apply(this, tmatrix);
tResult = bezierQ2Equation.apply(this, tmatrix);
}
// 高次方程
// 高次方程 1
else {
// TODO
// 求t2的参数方程
tmatrix = multi(tmatrix, 1 / tmatrix[4]);
var t4 = multi([
Math.pow(tmatrix[0], 2),
2 * tmatrix[0] * tmatrix[1],
2 * tmatrix[0] * tmatrix[2] + Math.pow(tmatrix[1], 2),
2 * tmatrix[1] * tmatrix[2],
Math.pow(tmatrix[2], 2)
], ymatrix[3]);
var t3 = multi([0, 0, tmatrix[0], tmatrix[1], tmatrix[2]], ymatrix[4]);
// 四次方程系数
var t5 = plus(t4, t3);
t5[2] = t5[2] - ymatrix[0];
t5[3] = t5[3] - ymatrix[1];
t5[4] = t5[4] - ymatrix[2];
tResult = bezierQ4Equation.apply(this, t5);
}
}
// 二次系数都为0
// 二次系数都为0 曲线2退化成直线
else if(xmatrix[3] == 0 && ymatrix[3] == 0){
// 一次系数都为0退化成一元二次方程
if(xmatrix[4] == 0 && ymatrix[4] == 0) {
tResult = bezierQuadeEquation.apply(this, tmatrix);
}
// 消去一次系数
else if(xmatrix[4] != 0 && ymatrix[4] != 0) {
if(xmatrix[4] != 0 && ymatrix[4] != 0) {
tmatrix = minus(multi(xmatrix, ymatrix[4]), multi(ymatrix, xmatrix[4]));
tResult = bezierQuadeEquation.apply(this, tmatrix);
tResult = bezierQ2Equation.apply(this, tmatrix);
}
// 一次系数有一个为0
else {
//TODO
// matrix[4] 系数为0, 曲线2退化成垂直线
else if(xmatrix[4] == 0) {
tResult = bezierQ2Equation.apply(this, xmatrix);
}
else if(ymatrix[4] == 0) {
tResult = bezierQ2Equation.apply(this, ymatrix);
}
}
// 二次系数有一个为0
else {
//TODO
// 代入法
// 置换矩阵
if (ymatrix[3] == 0) {
tmatrix = xmatrix;
xmatrix = ymatrix;
ymatrix = tmatrix;
}
// 退化成一元二次方程
if(xmatrix[4] == 0) {
tResult = bezierQ2Equation.apply(this, xmatrix);
}
// 同高次方程1
else {
tmatrix = multi(xmatrix, 1 / xmatrix[4]);
// 代入法求四次方程系数
tmatrix = [
ymatrix[3] * Math.pow(tmatrix[0], 2), // 4
2 * ymatrix[3] * tmatrix[0] * tmatrix[1] + ymatrix[4] * tmatrix[0], // 3
ymatrix[3] * (2 * tmatrix[0] * tmatrix[2] + Math.pow(tmatrix[1], 2)) + ymatrix[4] * tmatrix[2] - ymatrix[0], // 2
ymatrix[3] * 2 * tmatrix[1] * tmatrix[2] + ymatrix[4] * tmatrix[2] - ymatrix[1], // 1
ymatrix[3] * tmatrix[2] * tmatrix[2] - ymatrix[2] // 0
];
tResult = bezierQ4Equation.apply(this, tmatrix);
}
}
// t1 有解
if(tResult) {
var pair = [], t1, t2, t2Result = false;
for (var i = 0, l = tResult.length; i < l; i++) {
t1 = tResult[i];
// 代入求t2
t2Result = bezierQ2Equation(
xmatrix[3],
xmatrix[4],
-(xmatrix[0] * Math.pow(t1, 2) + xmatrix[1] * t1 + xmatrix[2])
);
if(t2Result) {
// 验证根是否成立
for (var j = 0, ll = t2Result.length; j < ll; j++) {
t2 = t2Result[j];
// 控制舍入误差,非必需
// if(
// true ||
// 0.0001 > Math.abs(
// ymatrix[0] * Math.pow(t1, 2) + ymatrix[1] * t1 + ymatrix[2]
// - (ymatrix[3] * Math.pow(t2, 2) + ymatrix[4] * t2)
// )
// ) {
pair.push([t1, t2]);
//}
}
}
}
// 求解xy坐标
return pair.length
? pair.map(function(item) {
return {
x: xmatrix[0] * Math.pow(t1, 2) + xmatrix[1] * t1 + p0.x,
y: ymatrix[0] * Math.pow(t1, 2) + ymatrix[1] * t1 + p0.y
};
})
: false;
}
}

View File

@@ -11,7 +11,7 @@ define(
function(require) {
var computeBoundingBox = require('./computeBoundingBox');
var bezierQuadraticEquation = require('../math/bezierQuadraticEquation');
var bezierQ2Equation = require('../math/bezierQ2Equation');
/**
* 判断x轴射线是否与贝塞尔曲线相交
@@ -53,7 +53,7 @@ define(
var b = 2 * (p1.y - p0.y);
var c = p0.y - p.y;
var tResult = bezierQuadraticEquation(a, b, c);
var tResult = bezierQ2Equation(a, b, c);
// 无解
if(!tResult) {

View File

@@ -1,5 +1,5 @@
/**
* @file bezierQuadraticEquation.js
* @file bezierQ2Equation.js
* @author mengke01
* @date
* @description
@@ -19,7 +19,7 @@ define(
* @param {number} c c系数
* @return {Array} 系数解
*/
function bezierQuadraticEquation(a, b, c) {
function bezierQ2Equation(a, b, c) {
var result = quadraticEquation(a, b, c);
if(!result) {
@@ -34,7 +34,7 @@ define(
: false;
}
return bezierQuadraticEquation;
return bezierQ2Equation;
}
);

View File

@@ -1,5 +1,5 @@
/**
* @file bezierQuarticEquation.js
* @file bezierQ4Equation.js
* @author mengke01
* @date
* @description