You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求三次函数cubic(x,p1,p2)的逆变换实现方案

JavaScript三次函数的逆变换实现

原函数化简与分析

首先将你提供的cubic函数化简,去掉冗余计算:

const p1 = 0.65;
const p2 = 1.2;

function cubic(x) {
  const cY = 3 * (p1 - 1);
  const bY = 3 * (p2 - p1) - cY;
  const aY = -1 - cY - bY;
  // 原返回值化简:1 - (aY*x³ + bY*x² + cY*x + 1) = -aY*x³ -bY*x² -cY*x
  return -aY * Math.pow(x, 3) - bY * Math.pow(x, 2) - cY * x;
}

该函数是一个三次多项式,输入x∈[0,1]输出对应y。要实现沿对角线y=x对称的逆函数,需满足:若y = cubic(x),则x = inverse(y),即逆函数能还原原函数的输入输出关系。

逆函数实现:牛顿迭代法

三次多项式的解析逆函数(卡尔达诺公式)代码繁琐且易有精度问题,因此采用牛顿迭代法求解数值解,适合前端场景快速得到高精度结果。

核心思路

  1. 对于输入y,求解方程cubic(x) = y,即f(x) = cubic(x) - y = 0
  2. 牛顿迭代公式:x_{n+1} = x_n - f(x_n)/f'(x_n),其中f'(x)是f(x)的导数
  3. 初始值取x0 = y(线性近似,靠近真实解),迭代3-5次即可收敛到足够精度

完整代码实现

const p1 = 0.65;
const p2 = 1.2;

// 预计算三次多项式系数,避免重复计算
const cY = 3 * (p1 - 1);
const bY = 3 * (p2 - p1) - cY;
const aY = -1 - cY - bY;

function cubic(x) {
  return -aY * Math.pow(x, 3) - bY * Math.pow(x, 2) - cY * x;
}

// 正确的逆函数实现
function inverse(y) {
  let x = y; // 初始值用线性近似
  // 迭代3次足够收敛(精度要求高可增加到5次)
  for (let i = 0; i < 3; i++) {
    // 计算f(x) = cubic(x) - y
    const fx = -aY * Math.pow(x, 3) - bY * Math.pow(x, 2) - cY * x - y;
    // 计算导数f'(x)
    const fPrimex = -3 * aY * Math.pow(x, 2) - 2 * bY * x - cY;
    // 牛顿迭代更新x
    x -= fx / fPrimex;
    // 限制x在[0,1]范围内,避免溢出
    x = Math.max(0, Math.min(1, x));
  }
  return x;
}

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);
    }
  }
}

draw(cvs.getContext('2d'), {
  blue: cubic,
  red: inverse,
  grey: linear
});

效果说明

替换原测试代码中的inverse函数后,红色逆函数曲线会与蓝色原函数曲线沿对角线y=x完美对称,符合你需要的效果。

内容的提问来源于stack exchange,提问作者RoyNeary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:20:22