好消息是我们可以找到关于贝塞尔曲线的各种信息。有几种形状查询技术(对于较低阶的曲线效果相当好,立方在较低的一侧:))。
S形三次贝塞尔曲线
首先,S形三次贝塞尔曲线有一个拐点。拐点是曲线上凹度变为凸度或相反的点。这也意味着在拐点处,曲线的曲率为零(嗯,如果任何曲线必须从凹形变为凸形,则必须在曲线笔直的位置之间存在某个位置——只需查看“S”)。
https://en.wikipedia.org/wiki/Inflection_point
参数曲线曲率的方程是

我们可以要求 Mathematica 简化这一点,以便我们可以进行一些快速测试。

这是一些 Javascript 代码(使用paper.js库),它们做同样的事情:
// Method1 - Find inflection points
function hasInflection(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y){
var CURV_EPSILON = 1e-3;
var e2 = 1 + CURV_EPSILON;
var roots = [], a, b, c;
// Solve for Numerator[k] == 0
// Where, Curvature k = (dx d^2y - d^2x dy) / (dx^2 - dy^2)^(3/2)
// Coefficients from Mathematica
a = -p1x*p0y + 2*p2x*p0y - p3x*p0y + p0x*p1y - 3*p2x*p1y + 2*p3x*p1y - 2*p0x*p2y + 3*p1x*p2y - p3x*p2y + p0x*p3y - 2*p1x*p3y + p2x*p3y;
b = (2*p1x*p0y - 3*p2x*p0y + p3x*p0y - 2*p0x*p1y + 3*p2x*p1y - p3x*p1y + 3*p0x*p2y - 3*p1x*p2y - p0x*p3y + p1x*p3y);
c = (-p1x*p0y + p2x*p0y + p0x*p1y - p2x*p1y - p0x*p2y + p1x*p2y);
// Use any method to solve the quadratic equation (a x^2 + b x + c = 0)
Numerical.solveQuadratic(a, b, c, roots, 0, 1);
// Find the root where, the curve changes from concave to convex
for (i = 0, l = roots.length; i < l; ++i) {
r = roots[i];
if( r > -CURV_EPSILON && r < e2 ){
// Here we basically evaluate the signed normals and look if they are of different signs
if( Curve.evaluate(v,r-CURV_EPSILON,3) * Curve.evaluate(v,r+CURV_EPSILON,3) < 0 )
return true;
}
}
return false;
}
或在此处查看完整示例
曲线,其中,任何 X 都有多个 Y 值
从你的问题来看,我认为有更好的定义你想要什么的空间。
即使曲线不是S形,任何 X(或反之亦然)都可能出现大于 Y 值的情况——曲率永远不会改变符号。

即使曲线不自相交也是如此。因此,对于您要查找的内容,这可能不是一个很好的测试。
如果您需要X 和 Y 方向单调的曲线——即 X 和 Y 值沿曲线长度单调递减或递增;您可以改为求解三次方程的导数(在 X 和 Y 中)。