y坐标为一个给定的x立方体贝塞尔立方体、坐标、塞尔

2023-09-11 01:57:04 作者:一炮轰了学校

这个问题是非常相似:二次贝塞尔曲线:Y?对于给定的X坐标。但是,这一个是立方...

我使用的是 getBezier 函数来计算贝塞尔曲线的Y坐标。贝塞尔曲线总是在(0,0)开始,并在(1,1)结束始终

我知道了X值,所以我试图将它插入%的(我是一个白痴)。但是,这并不能正常工作,效果显着。你可以提供一个解决方案?这是必要的它是一个白痴防爆功能。像:

 函数yFromX(C2X,c2y,C3X,c3y){// C1 =(0,0)和C4 =(1,1),domainc2和domainc3 = [0,1 ]
    //你的魔法
    返回是;
}
 

解决方案

由于这个问题十分有限(函数x(t)是单调的),我们或许可以蒙混过关使用pretty的解决方案为的廉价方法 - 二进制搜索

  VAR贝塞尔=功能(X0,Y0,X1,Y1,X2,Y2,X3,Y3,T){
    / *无论你使用的是计算曲线上的点* /
    返回不确定的; //我假定这将返回数组[X,Y]。
};

//我们实际需要的目标x值去与中间控制
//点​​,不是吗? ;)
变种yFromX =函数(xTarget,X1,Y1,X2,Y2){
  VAR xTolerance = 0.0001; //调整,请你
  VAR myBezier =函数(T){
    返回贝塞尔(0,0,X1,Y1,X2,Y2,1,1,t)的;
  };

  //我们可以做一些愚蠢的少,但由于x是单调
  //增加给定问题的限制,我们会做一个二进制搜索。

  //建立边界
  变种低级= 0;
  变种上部= 1;
  变种百分比=(上部+下部)/ 2;

  //获取初始x
  变种X = myBezier(百分比)[0];

  //循环,直到完成
  而(Math.abs(xTarget  -  X)> xTolerance){
    如果(xTarget&X的催化剂)
      低=个百分点;
    其他
      上=个百分点;

    百分比=(上部+下部)/ 2;
    X = myBezier(百分比)[0];
  }
  //我们在期望的x值容差。
  //返回的y值。
  返回myBezier(百分比)[1];
};
 
如图.点Q在直线y x上运动.点A的坐标为 1.0 .当线段AQ最短时.点Q的坐标为 . 青夏教育精英家教网

在某些输入这当然应该打破你的限制之外。

This question is very similar to: Quadratic bezier curve: Y coordinate for a given X?. But this one is cubic...

I'm using the getBezier function to calculate the Y coordinates of a bezier curve. The bezier curve starts always at (0,0) and ends always at (1,1).

I know the X value, so I tried to insert it as percent (I'm a moron). But that didn't work, obviously. Could you provide a solution? It's necessary it's an idiot proof function. Like:

function yFromX (c2x,c2y,c3x,c3y) { //c1 = (0,0) and c4 = (1,1), domainc2 and domainc3 = [0,1]
    //your magic
    return y;
}

解决方案

Since the problem is so limited (function x(t) is monotonic), we can probably get away with using a pretty cheap method of solution-- binary search.

var bezier = function(x0, y0, x1, y1, x2, y2, x3, y3, t) {
    /* whatever you're using to calculate points on the curve */
    return undefined; //I'll assume this returns array [x, y].
};

//we actually need a target x value to go with the middle control
//points, don't we? ;)
var yFromX = function(xTarget, x1, y1, x2, y2) {
  var xTolerance = 0.0001; //adjust as you please
  var myBezier = function(t) {
    return bezier(0, 0, x1, y1, x2, y2, 1, 1, t);
  };

  //we could do something less stupid, but since the x is monotonic
  //increasing given the problem constraints, we'll do a binary search.

  //establish bounds
  var lower = 0;
  var upper = 1;
  var percent = (upper + lower) / 2;

  //get initial x
  var x = myBezier(percent)[0];

  //loop until completion
  while(Math.abs(xTarget - x) > xTolerance) {
    if(xTarget > x) 
      lower = percent;
    else 
      upper = percent;

    percent = (upper + lower) / 2;
    x = myBezier(percent)[0];
  }
  //we're within tolerance of the desired x value.
  //return the y value.
  return myBezier(percent)[1];
};

This should certainly break on some inputs outside of your constraints.