Bezier曲线公式:
二次方程式:
以下是我的代码:
function SelectBezierCurve(pos_left, pos_top) {
for (var i = 0; i < allBezierCurves.length; i++) {
var d = allBezierCurves[i].EndX - 3 *
allBezierCurves[i].ControlPoint2X +
3 * allBezierCurves[i].ControlPoint1X -
allBezierCurves[i].StartX;
var a = 3 * (allBezierCurves[i].ControlPoint2X - 2 *
allBezierCurves[i].ControlPoint1X
+ allBezierCurves[i].StartX) / d;
var b = (allBezierCurves[i].ControlPoint1X -
allBezierCurves[i].StartX) / d;
var c = (allBezierCurves[i].StartX - pos_left) / d;
var p = (3 * b - a * a) / 3;
var q = (2 * a * a * a - 9 * a * b + 27 * c) / 27;
if (4 * p * p * p + 27 * q * q > 0) {
var c2 = -(p * p * p / 27);
if (q * q - 4 * c2 > 0) {
var sqrt = Math.sqrt(q * q - 4 * c2);
var z1 = (-q + sqrt) / 2;
var z2 = (-q - sqrt) / 2;
var tGivenX = -(a / 3) + Math.cbrt(z1) + Math.cbrt(z2);
var yOnBezierCurve = (1 - tGivenX) * (1 - tGivenX) *
(1 - tGivenX) * allBezierCurves[i].StartY + 3 *
tGivenX * (1 - tGivenX) * (1 - tGivenX) *
allBezierCurves[i].ControlPoint1Y + 3 * tGivenX *
tGivenX * (1 - tGivenX) *
allBezierCurves[i].ControlPoint2Y +
tGivenX * tGivenX * tGivenX *
allBezierCurves[i].EndY;
if (Math.abs(yOnBezierCurve - pos_top) < 5) {
if (selectedBezierCurve === i) {
FreeAllReferences();
} else {
selectedBezierCurve = i;
selectedSetOfPointsIndex = -1;
selectedEllipse = -1;
selectedCurve = -1;
selectedText = -1;
}
return true;
}
}
} else if (4 * p * p * p + 27 * q * q < 0) {
var k = (Math.acos(3 * q * Math.sqrt(3 / (-p)) / (2 * p))) /
3;
var tForKEquals0 = (-a) / 3 + 2 * Math.sqrt((-p) / 3) *
Math.cos(k);
var yOnBezierCurveTForKEquals0 = (1 - tForKEquals0) * (1 -
tForKEquals0) *
(1 - tForKEquals0) * allBezierCurves[i].StartY + 3 *
tForKEquals0 * (1 - tForKEquals0) * (1 - tForKEquals0) *
allBezierCurves[i].ControlPoint1Y + 3 * tForKEquals0 *
tForKEquals0 * (1 - tForKEquals0) *
allBezierCurves[i].ControlPoint2Y +
tForKEquals0 * tForKEquals0 * tForKEquals0 *
allBezierCurves[i].EndY;
if (Math.abs(yOnBezierCurveTForKEquals0 - pos_top) < 5) {
if (selectedBezierCurve === i) {
FreeAllReferences();
} else {
selectedBezierCurve = i;
selectedSetOfPointsIndex = -1;
selectedEllipse = -1;
selectedCurve = -1;
selectedText = -1;
}
return true;
} else {
k -= 2 * Math.PI / 3;
var tForKEquals1 = (-a) / 3 + 2 * Math.sqrt((-p) / 3) *
Math.cos(k);
var yOnBezierCurveTForKEquals1 = (1 - tForKEquals1) * (1
- tForKEquals1) *
(1 - tForKEquals1) * allBezierCurves[i].StartY + 3 *
tForKEquals1 * (1 - tForKEquals1) * (1 -
tForKEquals1) *
allBezierCurves[i].ControlPoint1Y + 3 * tForKEquals1
* tForKEquals1 * (1 - tForKEquals1) *
allBezierCurves[i].ControlPoint2Y +
tForKEquals1 * tForKEquals1 * tForKEquals1 *
allBezierCurves[i].EndY;
if (Math.abs(yOnBezierCurveTForKEquals1 - pos_top) < 5) {
if (selectedBezierCurve === i) {
FreeAllReferences();
} else {
selectedBezierCurve = i;
selectedSetOfPointsIndex = -1;
selectedEllipse = -1;
selectedCurve = -1;
selectedText = -1;
}
return true;
} else {
k *= 2;
var tForKEquals2 = (-a) / 3 + 2 * Math.sqrt((-p) / 3)
* Math.cos(k);
var yOnBezierCurveTForKEquals2 = (1 - tForKEquals2) *
(1 - tForKEquals2) *
(1 - tForKEquals2) * allBezierCurves[i].StartY +
3 * tForKEquals2 * (1 - tForKEquals2) * (1 -
tForKEquals2) *
allBezierCurves[i].ControlPoint1Y + 3 *
tForKEquals2 *
tForKEquals2 * (1 - tForKEquals2) *
allBezierCurves[i].ControlPoint2Y +
tForKEquals2 * tForKEquals2 * tForKEquals2 *
allBezierCurves[i].EndY;
if (Math.abs(yOnBezierCurveTForKEquals2 - pos_top) <
5) {
if (selectedBezierCurve === i) {
FreeAllReferences();
} else {
selectedBezierCurve = i;
selectedSetOfPointsIndex = -1;
selectedEllipse = -1;
selectedCurve = -1;
selectedText = -1;
}
return true;
}
}
}
}
}
return false;
}
在给定p1 = 67,324和p2 = 190,318以及p3 = 174,63和p4 = 292,58的情况下求解x,y = 181,188的Bezier曲线,使用下图进行公式简化我使用t表示x = 181是来到t = 1.41745。
在给定x = 181和t = 1.41745的情况下计算的y是y = 218,甚至不接近188,这是我期待的距离它不远的值。
我只对y给定x以及起始端和控制点坐标的真实根解决方案感兴趣。
PX = 181,P1X = 67,P2X = 190,P3X = 174,P4X = 292
py =试图解决这个问题
P1Y = 324,P2Y = 318,P3Y = 63,P4Y = 58
要提供上下文,我试图找出用户鼠标是否单击Bezier曲线。因此,我考虑使用x鼠标点击坐标的上述图片方程式求解y并检查结果y是否足够接近相应的鼠标点击y将显示用户点击了Bezier曲线。
图中的公式简化为计算机可以计算atm的位置。如果三次方程的实根不完整,请给出三次方程的所有实根的正确公式。