简体   繁体   中英

Inverse of cubic function

I'm trying to create the inverse transform of the following function:

function cubic(x, p1, p2) {

  // coefficients
  const cY = 3 * (p1 - 1);
  const bY = 3 * (p2 - p1) - cY;
  const aY = -1 - cY - bY;

  return 1 - ((aY * pow(x, 3)) + (bY * pow(x, 2)) + (cY * x) + 1);

}

The function expects x to be in the range of 0-1 and returns y .

I need to find the inverse of this function to create a curve that is mirrored across the diagonal such that the blue and red curves in the below example produce a perfectly symmetrical shape.

I've tried to invert the transform via 1 - cubic(1 - x, p1, p2) , switching p1 and p2, negating p1 and p2 etc but nothing is giving me the correct results. Any help greatly appreciated!

Here's a Javascript Sandbox for the problem on JS Fiddle

左侧显示我当前的反函数(红色),这是幼稚和错误的。右侧显示正确逆变换的近似图(绿色)

 const p1 = 0.65; const p2 = 1.2; draw(cvs.getContext('2d'), { blue: cubic, red: inverse, grey: linear }); function cubic(x) { // coefficients const cY = 3 * (p1 - 1); const bY = 3 * (p2 - p1) - cY; const aY = -1 - cY - bY; return 1 - ((aY * Math.pow(x, 3)) + (bY * Math.pow(x, 2)) + (cY * x) + 1); } // TODO: Correct inverse of the above forward transform function inverse(x) { return 1 - cubic(1 - x, p1, p2); } function linear(x) { return x; } function draw(ctx, fx) { const w = ctx.canvas.width * devicePixelRatio; const h = ctx.canvas.height * devicePixelRatio; ctx.clearRect(0, 0, w, h); ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)'; const blockWidth = w / 10; const blockHeight = h / 10; for (let x = 0; x < w; x += blockWidth) { for (let y = 0; y < h; y += blockHeight) { ctx.strokeRect(x, y, blockWidth, blockHeight); } } for (const color in fx) { ctx.fillStyle = color; for (let i = 0, x, y; i < w; i++) { x = i / (w - 1); y = 1.0 - fx[color](x); ctx.fillRect(Math.round(x * w) - 1, Math.round(y * h) - 1, 2, 2); } } }
 <canvas id="cvs" width="768" height="768" style="background:black;"></canvas>

The inverse of such a cubic may not even be a function.

But you can at least plot it by swapping the coordinates

   y = myfunc(x);
   plot(x,y, 'blue');  // your original function
   plot(y,x, 'green'); // this is the inverse of x,y along the line x-y=0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM